You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

850 lines
26 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: atlstl/string/ccombstr_veneer.hpp
  3. *
  4. * Purpose: Contains the definition of the ccombstr_veneer template.
  5. *
  6. * Created: 1st October 2002
  7. * Updated: 10th August 2009
  8. *
  9. * Home: http://stlsoft.org/
  10. *
  11. * Copyright (c) 2002-2009, Matthew Wilson and Synesis Software
  12. * All rights reserved.
  13. *
  14. * Redistribution and use in source and binary forms, with or without
  15. * modification, are permitted provided that the following conditions are met:
  16. *
  17. * - Redistributions of source code must retain the above copyright notice, this
  18. * list of conditions and the following disclaimer.
  19. * - Redistributions in binary form must reproduce the above copyright notice,
  20. * this list of conditions and the following disclaimer in the documentation
  21. * and/or other materials provided with the distribution.
  22. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
  23. * any contributors may be used to endorse or promote products derived from
  24. * this software without specific prior written permission.
  25. *
  26. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  27. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  29. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  30. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  31. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  32. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  33. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  34. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  35. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  36. * POSSIBILITY OF SUCH DAMAGE.
  37. *
  38. * ////////////////////////////////////////////////////////////////////// */
  39. /** \file atlstl/string/ccombstr_veneer.hpp
  40. *
  41. * \brief [C++] Definition of the atlstl::ccombstr_veneer class
  42. * (\ref group__library__string "String" Library).
  43. */
  44. #ifndef ATLSTL_INCL_ATLSTL_STRING_HPP_CCOMBSTR_VENEER
  45. #define ATLSTL_INCL_ATLSTL_STRING_HPP_CCOMBSTR_VENEER
  46. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  47. # define ATLSTL_VER_ATLSTL_STRING_HPP_CCOMBSTR_VENEER_MAJOR 5
  48. # define ATLSTL_VER_ATLSTL_STRING_HPP_CCOMBSTR_VENEER_MINOR 3
  49. # define ATLSTL_VER_ATLSTL_STRING_HPP_CCOMBSTR_VENEER_REVISION 1
  50. # define ATLSTL_VER_ATLSTL_STRING_HPP_CCOMBSTR_VENEER_EDIT 76
  51. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  52. /* /////////////////////////////////////////////////////////////////////////
  53. * Compatibility
  54. */
  55. /*
  56. [Incompatibilies-start]
  57. STLSOFT_COMPILER_IS_MSVC: _MSC_VER<1200
  58. [Incompatibilies-end]
  59. */
  60. /* /////////////////////////////////////////////////////////////////////////
  61. * Includes
  62. */
  63. #ifndef ATLSTL_INCL_ATLSTL_HPP_ATLSTL
  64. # include <atlstl/atlstl.hpp>
  65. #endif /* !ATLSTL_INCL_ATLSTL_HPP_ATLSTL */
  66. #ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER
  67. # include <stlsoft/util/std/iterator_helper.hpp>
  68. #endif /* !STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER */
  69. #ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_CONSTRAINTS
  70. # include <stlsoft/util/constraints.hpp>
  71. #endif /* !STLSOFT_INCL_STLSOFT_UTIL_HPP_CONSTRAINTS */
  72. #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER
  73. # include <stlsoft/memory/auto_buffer.hpp>
  74. #endif /* !STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER */
  75. #if defined(STLSOFT_COMPILER_IS_DMC)
  76. # ifndef STLSOFT_INCL_STLSOFT_CONVERSION_HPP_SAP_CAST
  77. # include <stlsoft/conversion/sap_cast.hpp>
  78. # endif /* !STLSOFT_INCL_STLSOFT_CONVERSION_HPP_SAP_CAST */
  79. #endif /* compiler */
  80. #ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_STRING_TRAITS_FWD
  81. # include <stlsoft/string/string_traits_fwd.hpp>
  82. #endif /* !STLSOFT_INCL_STLSOFT_STRING_HPP_STRING_TRAITS_FWD */
  83. #ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER
  84. # include <stlsoft/util/std/iterator_helper.hpp>
  85. #endif /* !STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER */
  86. #ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_STD_SWAP
  87. # include <stlsoft/util/std_swap.hpp>
  88. #endif /* !STLSOFT_INCL_STLSOFT_UTIL_HPP_STD_SWAP */
  89. #ifndef STLSOFT_INCL_H_WCHAR
  90. # define STLSOFT_INCL_H_WCHAR
  91. # include <wchar.h> // for wcscmp(), _wcsnset()
  92. #endif /* !STLSOFT_INCL_H_WCHAR */
  93. /* /////////////////////////////////////////////////////////////////////////
  94. * Namespace
  95. */
  96. #ifndef _ATLSTL_NO_NAMESPACE
  97. # if defined(_STLSOFT_NO_NAMESPACE) || \
  98. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  99. /* There is no stlsoft namespace, so must define ::atlstl */
  100. namespace atlstl
  101. {
  102. # else
  103. /* Define stlsoft::atlstl_project */
  104. namespace stlsoft
  105. {
  106. namespace atlstl_project
  107. {
  108. # endif /* _STLSOFT_NO_NAMESPACE */
  109. #endif /* !_ATLSTL_NO_NAMESPACE */
  110. /* /////////////////////////////////////////////////////////////////////////
  111. * Classes
  112. */
  113. /** \brief Applies standard string (std::basic_string) interface to the CComBSTR class
  114. *
  115. * \ingroup group__library__string
  116. *
  117. * This class adapts the ATL string type CComBSTR to express a standard String-like interface
  118. *
  119. * \ingroup concepts_veneer
  120. */
  121. // [[synesis:class:string: atlstl::ccombstr_veneer]]
  122. class ccombstr_veneer
  123. #ifdef _ATLSTL_CCOMBSTR_VENEER_INHERIT_AS_PUBLIC
  124. : public CComBSTR
  125. #else /* ? _ATLSTL_CCOMBSTR_VENEER_INHERIT_AS_PUBLIC */
  126. # if defined(STLSOFT_COMPILER_IS_DMC)
  127. : protected CComBSTR
  128. # else /* ? compiler */
  129. : private CComBSTR
  130. # endif /* compiler */
  131. #endif /* _ATLSTL_CCOMBSTR_VENEER_INHERIT_AS_PUBLIC */
  132. {
  133. private:
  134. typedef CComBSTR parent_class_type;
  135. typedef ccombstr_veneer class_type;
  136. public:
  137. /// The value type
  138. typedef OLECHAR value_type;
  139. /// The mutating iterator type
  140. typedef LPOLESTR iterator;
  141. /// The non-mutating (const) iterator type
  142. typedef LPCOLESTR const_iterator;
  143. /// The pointer type
  144. typedef LPOLESTR pointer;
  145. /// The pointer-to-const type
  146. typedef LPCOLESTR const_pointer;
  147. /// The reference type
  148. typedef OLECHAR& reference;
  149. /// The reference-to-const type
  150. typedef OLECHAR const& const_reference;
  151. /// The size type
  152. typedef as_size_t size_type;
  153. /// The difference type
  154. typedef as_ptrdiff_t difference_type;
  155. #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
  156. // typedef stlsoft_ns_qual(reverse_iterator_base)< iterator
  157. // , value_type
  158. // , reference
  159. // , pointer
  160. // , difference_type
  161. // > reverse_iterator;
  162. typedef stlsoft_ns_qual(const_reverse_iterator_base)< const_iterator
  163. , value_type const
  164. , const_reference
  165. , const_pointer
  166. , difference_type
  167. > const_reverse_iterator;
  168. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  169. // Construction
  170. public:
  171. /// Default constructor
  172. ccombstr_veneer();
  173. /// Copy constructor
  174. ccombstr_veneer(class_type const& rhs);
  175. /// Copy constructor
  176. ss_explicit_k ccombstr_veneer(CComBSTR const& rhs);
  177. /// Construct from an ANSI string
  178. ss_explicit_k ccombstr_veneer(LPCSTR s);
  179. /// Construct from a Unicode string
  180. ss_explicit_k ccombstr_veneer(LPCWSTR s);
  181. /// Construct from a range
  182. ccombstr_veneer(LPCOLESTR from, LPCOLESTR to);
  183. /// Construct from a range
  184. ccombstr_veneer(size_type length, LPCOLESTR from);
  185. ///
  186. ccombstr_veneer(as_size_t cch, OLECHAR ch);
  187. /// Copy assignment operator
  188. class_type const& operator =(class_type const& rhs);
  189. /// Copy assignment operator
  190. class_type const& operator =(CComBSTR const& rhs);
  191. /// Assignment operator
  192. class_type const& operator =(LPCSTR s);
  193. /// Assignment operator
  194. class_type const& operator =(LPCWSTR s);
  195. // Iteration
  196. public:
  197. /// Begins the iteration
  198. ///
  199. /// \return An iterator representing the start of the sequence
  200. const_iterator begin() const;
  201. /// Ends the iteration
  202. ///
  203. /// \return An iterator representing the end of the sequence
  204. const_iterator end() const;
  205. #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
  206. /// Begins the reverse iteration
  207. ///
  208. /// \return A non-mutable (const) iterator representing the start of the reverse sequence
  209. const_reverse_iterator rbegin() const;
  210. /// Ends the reverse iteration
  211. ///
  212. /// \return A non-mutable (const) iterator representing the end of the reverse sequence
  213. const_reverse_iterator rend() const;
  214. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  215. // Access
  216. public:
  217. reference operator [](size_type index);
  218. const_reference operator [](size_type index) const;
  219. // Operations
  220. public:
  221. void swap(class_type& rhs);
  222. // Attributes
  223. public:
  224. /// Provides access to the underlying CComBSTR type
  225. CComBSTR &get_base_type();
  226. /// Provides access to the underlying CComBSTR type
  227. CComBSTR const &get_base_type() const;
  228. /// Returns the number of elements in the sequence
  229. size_type length() const;
  230. /// Returns the number of elements in the sequence
  231. size_type size() const;
  232. /// \brief Indicates whether the sequence is empty
  233. as_bool_t empty() const;
  234. /// Returns a pointer to constant data representing the managed string
  235. const_pointer c_str() const;
  236. /// Returns a pointer to constant data representing the managed string
  237. const_pointer data() const;
  238. };
  239. /* /////////////////////////////////////////////////////////////////////////
  240. * Helper functions
  241. */
  242. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  243. // Because CComBSTR converts into BSTR, and because BSTR and BSTR are pointers
  244. // which can be combined, and because LPCWSTR is *not* BSTR, and because
  245. // CComBSTR can be implicitly constructed from LPCSTR, BSTR and LPCWSTR, it is
  246. // incredibly easy to think you're doing value comparison but actually be doing
  247. // identity comparison. Filth!!!!!!!
  248. //
  249. // Furthermore, old versions of CComBSTR don't have operator ==(), and even
  250. // newer versions define it as a member function, instead of a free function.
  251. // Triple filth!!!!!
  252. //
  253. // So, to ensure that CComBSTR is compared appropriately, all comparisons must
  254. // filter through this function, which takes parameters by pointer (to avoid the
  255. // implicit conversions) and explicitly calls the operator ==() to avoid identity
  256. // comparison.
  257. inline int atlstl_safe_wcscmp(LPCOLESTR s1, LPCOLESTR s2)
  258. {
  259. return (NULL == s1)
  260. ? (NULL == s2)
  261. ? 0
  262. : 1
  263. : (NULL == s2)
  264. ? -1
  265. : wcscmp(s1, s2);
  266. }
  267. inline int atlstl_safe_wcscmp(LPCOLESTR s1, LPCSTR s2)
  268. {
  269. USES_CONVERSION;
  270. return atlstl_safe_wcscmp(s1, (NULL == s2) ? L"" : A2CW(s2));
  271. }
  272. inline int atlstl_safe_wcscmp(LPCSTR s1, LPCOLESTR s2)
  273. {
  274. USES_CONVERSION;
  275. return atlstl_safe_wcscmp((NULL == s1) ? L"" : A2CW(s1), s2);
  276. }
  277. #if 0
  278. // _ATL_VER 0x0800
  279. bool CComBSTR::operator==(CComBSTR const& bstrSrc) const throw()
  280. bool CComBSTR::operator==(LPCOLESTR pszSrc) const
  281. bool CComBSTR::operator==(LPOLESTR pszSrc) const
  282. bool CComBSTR::operator==(int nNull) const throw() // Can you believe it!!
  283. bool CComBSTR::operator==(LPCSTR pszSrc) const
  284. // _ATL_VER 0x0710
  285. bool CComBSTR::operator==(CComBSTR const& bstrSrc) const throw()
  286. bool CComBSTR::operator==(LPCOLESTR pszSrc) const
  287. bool CComBSTR::operator==(LPOLESTR pszSrc) const
  288. bool CComBSTR::operator==(int nNull) const throw() // Can you believe it!!
  289. bool CComBSTR::operator==(LPCSTR pszSrc) const
  290. // _ATL_VER 0x0700
  291. bool CComBSTR::operator==(CComBSTR const& bstrSrc) const throw()
  292. bool CComBSTR::operator==(LPCOLESTR pszSrc) const
  293. bool CComBSTR::operator==(int nNull) const throw()
  294. bool CComBSTR::operator==(LPCSTR pszSrc) const
  295. // _ATL_VER 0x0300
  296. bool CComBSTR::operator==(BSTR bstrSrc) const
  297. bool CComBSTR::operator==(LPCSTR pszSrc) const
  298. // _ATL_VER 0x0202
  299. #endif /* 0 */
  300. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  301. /* /////////////////////////////////////////////////////////////////////////
  302. * Operators
  303. */
  304. inline as_bool_t operator ==(ccombstr_veneer const& lhs, ccombstr_veneer const& rhs)
  305. {
  306. CComBSTR const& lhs_ = lhs.get_base_type();
  307. CComBSTR const& rhs_ = rhs.get_base_type();
  308. #if _ATL_VER >= 0x0700
  309. return lhs_ == rhs_;
  310. #else // ? _ATL_VER
  311. return 0 == atlstl_safe_wcscmp(lhs_, rhs_);
  312. #endif // _ATL_VER
  313. }
  314. #if !defined(STLSOFT_COMPILER_IS_MSVC) || \
  315. _MSC_VER >= 1200
  316. inline as_bool_t operator ==(LPCSTR lhs, ccombstr_veneer const& rhs)
  317. {
  318. CComBSTR const& rhs_ = rhs.get_base_type();
  319. #if _ATL_VER >= 0x0300
  320. return rhs_ == lhs;
  321. #else /* ? _ATL_VER */
  322. return 0 == atlstl_safe_wcscmp(lhs, rhs_);
  323. #endif /* _ATL_VER */
  324. }
  325. inline as_bool_t operator ==(ccombstr_veneer const& lhs, LPCSTR rhs)
  326. {
  327. CComBSTR const& lhs_ = lhs.get_base_type();
  328. #if _ATL_VER >= 0x0300
  329. return lhs_ == rhs;
  330. #else /* ? _ATL_VER */
  331. return 0 == atlstl_safe_wcscmp(lhs_, rhs);
  332. #endif /* _ATL_VER */
  333. }
  334. #endif /* !(_MSC_VER < 1200) */
  335. inline as_bool_t operator ==(LPCWSTR lhs, ccombstr_veneer const& rhs)
  336. {
  337. CComBSTR const& rhs_ = rhs.get_base_type();
  338. #if _ATL_VER >= 0x0700
  339. return rhs_ == lhs;
  340. #else // ? _ATL_VER
  341. return 0 == atlstl_safe_wcscmp(lhs, rhs_);
  342. #endif // _ATL_VER
  343. }
  344. inline as_bool_t operator ==(ccombstr_veneer const& lhs, LPCWSTR rhs)
  345. {
  346. CComBSTR const& lhs_ = lhs.get_base_type();
  347. #if _ATL_VER >= 0x0700
  348. return lhs_ == rhs;
  349. #else // ? _ATL_VER
  350. return 0 == atlstl_safe_wcscmp(lhs_, rhs);
  351. #endif // _ATL_VER
  352. }
  353. inline as_bool_t operator !=(ccombstr_veneer const& lhs, ccombstr_veneer const& rhs)
  354. {
  355. return !operator ==(lhs, rhs);
  356. }
  357. #if !defined(STLSOFT_COMPILER_IS_MSVC) || \
  358. _MSC_VER >= 1200
  359. inline as_bool_t operator !=(LPCSTR lhs, ccombstr_veneer const& rhs)
  360. {
  361. return !operator ==(lhs, rhs);
  362. }
  363. inline as_bool_t operator !=(ccombstr_veneer const& lhs, LPCSTR rhs)
  364. {
  365. return !operator ==(lhs, rhs);
  366. }
  367. #endif /* !(_MSC_VER < 1200) */
  368. inline as_bool_t operator !=(LPCWSTR lhs, ccombstr_veneer const& rhs)
  369. {
  370. return !operator ==(lhs, rhs);
  371. }
  372. inline as_bool_t operator !=(ccombstr_veneer const& lhs, LPCWSTR rhs)
  373. {
  374. return !operator ==(lhs, rhs);
  375. }
  376. /* /////////////////////////////////////////////////////////////////////////
  377. * swapping
  378. */
  379. inline void swap(ccombstr_veneer& lhs, ccombstr_veneer& rhs)
  380. {
  381. lhs.swap(rhs);
  382. }
  383. /* /////////////////////////////////////////////////////////////////////////
  384. * Shims
  385. */
  386. /** \brief \ref group__concept__shim__string_access__c_str_data for comstl::ccombstr_veneer
  387. *
  388. * \ingroup group__concept__shim__string_access
  389. */
  390. inline LPCOLESTR c_str_data(atlstl_ns_qual(ccombstr_veneer) const& str)
  391. {
  392. return str.data();
  393. }
  394. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  395. inline LPCOLESTR c_str_data_w(atlstl_ns_qual(ccombstr_veneer) const& str) { return c_str_data(str); }
  396. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  397. /** \brief \ref group__concept__shim__string_access__c_str_len for comstl::ccombstr_veneer
  398. *
  399. * \ingroup group__concept__shim__string_access
  400. */
  401. inline as_size_t c_str_len(atlstl_ns_qual(ccombstr_veneer) const& str)
  402. {
  403. return str.length();
  404. }
  405. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  406. inline as_size_t c_str_len_w(atlstl_ns_qual(ccombstr_veneer) const& str) { return c_str_len(str); }
  407. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  408. /** \brief \ref group__concept__shim__string_access__c_str_ptr for comstl::ccombstr_veneer
  409. *
  410. * \ingroup group__concept__shim__string_access
  411. */
  412. inline LPCOLESTR c_str_ptr(atlstl_ns_qual(ccombstr_veneer) const& str)
  413. {
  414. return str.c_str();
  415. }
  416. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  417. inline LPCOLESTR c_str_ptr_w(atlstl_ns_qual(ccombstr_veneer) const& str) { return c_str_ptr(str); }
  418. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  419. /** \brief \ref group__concept__shim__string_access__c_str_ptr_null for comstl::ccombstr_veneer
  420. *
  421. * \ingroup group__concept__shim__string_access
  422. */
  423. inline LPCOLESTR c_str_ptr_null(atlstl_ns_qual(ccombstr_veneer) const& str)
  424. {
  425. return !str.empty() ? str.c_str() : NULL;
  426. }
  427. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  428. inline LPCOLESTR c_str_ptr_null_w(atlstl_ns_qual(ccombstr_veneer) const& str) { return c_str_ptr_null(str); }
  429. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  430. /** \brief \ref group__concept__shim__stream_insertion "stream insertion shim" for comstl::ccombstr_veneer
  431. *
  432. * \ingroup group__concept__shim__stream_insertion
  433. */
  434. template<ss_typename_param_k S>
  435. inline S& operator <<(S& s, atlstl_ns_qual(ccombstr_veneer) const& str)
  436. {
  437. s << str.c_str();
  438. return s;
  439. }
  440. /* /////////////////////////////////////////////////////////////////////////
  441. * Unit-testing
  442. */
  443. #ifdef STLSOFT_UNITTEST
  444. # include "./unittest/ccombstr_veneer_unittest_.h"
  445. #endif /* STLSOFT_UNITTEST */
  446. /* /////////////////////////////////////////////////////////////////////////
  447. * Implementation
  448. */
  449. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  450. inline ccombstr_veneer::ccombstr_veneer()
  451. : parent_class_type()
  452. {
  453. stlsoft_constraint_must_be_same_size(CComBSTR, class_type);
  454. }
  455. inline ccombstr_veneer::ccombstr_veneer(class_type const& rhs)
  456. : parent_class_type(rhs)
  457. {
  458. stlsoft_constraint_must_be_same_size(CComBSTR, class_type);
  459. }
  460. inline ccombstr_veneer::ccombstr_veneer(CComBSTR const& rhs)
  461. : parent_class_type(rhs)
  462. {
  463. stlsoft_constraint_must_be_same_size(CComBSTR, class_type);
  464. }
  465. inline ccombstr_veneer::ccombstr_veneer(LPCSTR s)
  466. /* There's a bug in some implementations of ATL 3.x, so we go for the assigment,
  467. * doing the conversion ourselves
  468. */
  469. #if _ATL_VER >= 0x0700
  470. : parent_class_type(s)
  471. #endif /* _ATL_VER */
  472. {
  473. #if _ATL_VER < 0x0700
  474. USES_CONVERSION;
  475. *this = A2COLE(s);
  476. #endif /* _ATL_VER */
  477. ATLSTL_ASSERT(s == NULL || length() == strlen(s));
  478. stlsoft_constraint_must_be_same_size(CComBSTR, class_type);
  479. }
  480. inline ccombstr_veneer::ccombstr_veneer(LPCWSTR s)
  481. #if _ATL_VER >= 0x0300
  482. : parent_class_type(s)
  483. #endif /* _ATL_VER */
  484. {
  485. #if _ATL_VER < 0x0300
  486. USES_CONVERSION;
  487. *this = s;
  488. #endif /* _ATL_VER */
  489. ATLSTL_ASSERT(s == NULL || length() == wcslen(s));
  490. stlsoft_constraint_must_be_same_size(CComBSTR, class_type);
  491. }
  492. inline ccombstr_veneer::ccombstr_veneer(LPCOLESTR from, LPCOLESTR to)
  493. : parent_class_type(static_cast<int>(to - from), from)
  494. {
  495. stlsoft_constraint_must_be_same_size(CComBSTR, class_type);
  496. }
  497. inline void ccombstr_veneer::swap(ccombstr_veneer::class_type& rhs)
  498. {
  499. std_swap(m_str, rhs.m_str);
  500. }
  501. inline ccombstr_veneer::ccombstr_veneer(ccombstr_veneer::size_type length, LPCOLESTR from)
  502. : parent_class_type(static_cast<int>(length), from)
  503. {
  504. stlsoft_constraint_must_be_same_size(CComBSTR, class_type);
  505. }
  506. inline ccombstr_veneer::ccombstr_veneer(as_size_t cch, OLECHAR ch)
  507. {
  508. stlsoft_constraint_must_be_same_size(CComBSTR, class_type);
  509. typedef stlsoft_ns_qual(auto_buffer)<OLECHAR> buffer_t;
  510. buffer_t buffer(cch);
  511. _wcsnset(&buffer[0], ch, cch);
  512. class_type(cch, buffer.data()).swap(*this);
  513. }
  514. inline ccombstr_veneer::class_type const& ccombstr_veneer::operator =(ccombstr_veneer::class_type const& rhs)
  515. {
  516. parent_class_type::operator =(rhs);
  517. return *this;
  518. }
  519. inline ccombstr_veneer::class_type const& ccombstr_veneer::operator =(CComBSTR const& rhs)
  520. {
  521. parent_class_type::operator =(rhs);
  522. return *this;
  523. }
  524. inline ccombstr_veneer::class_type const& ccombstr_veneer::operator =(LPCSTR s)
  525. {
  526. /* There's a bug in some implementations of ATL 3.x, so we go for the assigment,
  527. * doing the conversion ourselves
  528. */
  529. #if _ATL_VER >= 0x0700
  530. parent_class_type::operator =(s);
  531. #else /* ? _ATL_VER */
  532. USES_CONVERSION;
  533. *this = A2COLE(s);
  534. #endif /* _ATL_VER */
  535. return *this;
  536. }
  537. inline ccombstr_veneer::class_type const& ccombstr_veneer::operator =(LPCWSTR s)
  538. {
  539. parent_class_type::operator =(s);
  540. return *this;
  541. }
  542. inline ccombstr_veneer::const_iterator ccombstr_veneer::begin() const
  543. {
  544. return *this;
  545. }
  546. inline ccombstr_veneer::const_iterator ccombstr_veneer::end() const
  547. {
  548. return begin() + Length();
  549. }
  550. #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
  551. inline ccombstr_veneer::const_reverse_iterator ccombstr_veneer::rbegin() const
  552. {
  553. return const_reverse_iterator(end());
  554. }
  555. inline ccombstr_veneer::const_reverse_iterator ccombstr_veneer::rend() const
  556. {
  557. return const_reverse_iterator(begin());
  558. }
  559. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  560. inline ccombstr_veneer::reference ccombstr_veneer::operator [](ccombstr_veneer::size_type index)
  561. {
  562. ATLSTL_MESSAGE_ASSERT("Index out of range", index < length());
  563. return const_cast<reference>(data()[index]);
  564. }
  565. inline ccombstr_veneer::const_reference ccombstr_veneer::operator [](ccombstr_veneer::size_type index) const
  566. {
  567. ATLSTL_MESSAGE_ASSERT("Index out of range", index < length());
  568. return data()[index];
  569. }
  570. inline CComBSTR &ccombstr_veneer::get_base_type()
  571. {
  572. #if defined(STLSOFT_COMPILER_IS_DMC)
  573. CComBSTR *this_ = stlsoft_ns_qual(sap_cast)<CComBSTR*>(this);
  574. #else /* ? compiler */
  575. CComBSTR *this_ = this;
  576. #endif /* compiler */
  577. return *this_;
  578. }
  579. inline CComBSTR const& ccombstr_veneer::get_base_type() const
  580. {
  581. #if defined(STLSOFT_COMPILER_IS_DMC)
  582. CComBSTR const *this_ = stlsoft_ns_qual(sap_cast)<CComBSTR const*>(this);
  583. #else /* ? compiler */
  584. CComBSTR const *this_ = this;
  585. #endif /* compiler */
  586. return *this_;
  587. }
  588. inline ccombstr_veneer::size_type ccombstr_veneer::length() const
  589. {
  590. return Length();
  591. }
  592. inline ccombstr_veneer::size_type ccombstr_veneer::size() const
  593. {
  594. return length();
  595. }
  596. inline as_bool_t ccombstr_veneer::empty() const
  597. {
  598. return length() == 0;
  599. }
  600. inline ccombstr_veneer::const_pointer ccombstr_veneer::c_str() const
  601. {
  602. return empty() ? L"" : static_cast<const_pointer>(*this);
  603. }
  604. inline ccombstr_veneer::const_pointer ccombstr_veneer::data() const
  605. {
  606. return empty() ? L"" : static_cast<const_pointer>(*this);
  607. }
  608. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  609. /* ////////////////////////////////////////////////////////////////////// */
  610. #ifndef _ATLSTL_NO_NAMESPACE
  611. # if defined(_STLSOFT_NO_NAMESPACE) || \
  612. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  613. } // namespace atlstl
  614. # else
  615. } // namespace atlstl_project
  616. } // namespace stlsoft
  617. # endif /* _STLSOFT_NO_NAMESPACE */
  618. #endif /* !_ATLSTL_NO_NAMESPACE */
  619. #if defined(STLSOFT_CF_std_NAMESPACE)
  620. namespace stlsoft
  621. {
  622. inline void swap(atlstl_ns_qual(ccombstr_veneer)& lhs, atlstl_ns_qual(ccombstr_veneer)& rhs)
  623. {
  624. lhs.swap(rhs);
  625. }
  626. } // namespace stlsoft
  627. #endif /* STLSOFT_CF_std_NAMESPACE */
  628. /* /////////////////////////////////////////////////////////////////////////
  629. * Namespace
  630. *
  631. * The string access shims exist either in the stlsoft namespace, or in the
  632. * global namespace. This is required by the lookup rules.
  633. *
  634. */
  635. #ifndef _ATLSTL_NO_NAMESPACE
  636. # if !defined(_STLSOFT_NO_NAMESPACE) && \
  637. !defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  638. namespace stlsoft
  639. {
  640. # else /* ? _STLSOFT_NO_NAMESPACE */
  641. /* There is no stlsoft namespace, so must define in the global namespace */
  642. # endif /* !_STLSOFT_NO_NAMESPACE */
  643. using ::atlstl::c_str_data;
  644. using ::atlstl::c_str_data_w;
  645. using ::atlstl::c_str_len;
  646. using ::atlstl::c_str_len_w;
  647. using ::atlstl::c_str_ptr;
  648. using ::atlstl::c_str_ptr_w;
  649. using ::atlstl::c_str_ptr_null;
  650. using ::atlstl::c_str_ptr_null_w;
  651. /* /////////////////////////////////////////////////////////////////////////
  652. * Traits
  653. */
  654. /** Specialisation for atlstl::ccombstr_veneer
  655. */
  656. STLSOFT_TEMPLATE_SPECIALISATION
  657. struct string_traits< ::atlstl::ccombstr_veneer>
  658. {
  659. typedef ::atlstl::ccombstr_veneer value_type;
  660. typedef ::atlstl::ccombstr_veneer::value_type char_type; // NOTE: Can't use value_type::value_type here, because of BC++ 5.5.1
  661. typedef value_type::size_type size_type;
  662. typedef char_type const const_char_type;
  663. typedef value_type string_type;
  664. typedef string_type::pointer pointer;
  665. typedef string_type::const_pointer const_pointer;
  666. typedef string_type::iterator iterator;
  667. typedef string_type::const_iterator const_iterator;
  668. #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
  669. // typedef string_type::reverse_iterator reverse_iterator;
  670. typedef string_type::const_reverse_iterator const_reverse_iterator;
  671. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  672. enum
  673. {
  674. is_pointer = false
  675. , is_pointer_to_const = false
  676. , char_type_size = sizeof(char_type)
  677. };
  678. static string_type empty_string()
  679. {
  680. return string_type();
  681. }
  682. static string_type construct(string_type const& src, size_type pos, size_type len)
  683. {
  684. return string_type(len, src.data() + pos);
  685. }
  686. # ifdef STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT
  687. template <ss_typename_param_k I>
  688. static string_type &assign_inplace(string_type &str, I first, I last)
  689. # else /* ? STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT */
  690. static string_type &assign_inplace(string_type &str, const_iterator first, const_iterator last)
  691. # endif /* STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT */
  692. {
  693. // comstl::bstr cannot assign in-place
  694. return (str = string_type(last - first, first), str);
  695. }
  696. };
  697. # if !defined(_STLSOFT_NO_NAMESPACE) && \
  698. !defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  699. } // namespace stlsoft
  700. # else /* ? _STLSOFT_NO_NAMESPACE */
  701. /* There is no stlsoft namespace, so must define in the global namespace */
  702. # endif /* !_STLSOFT_NO_NAMESPACE */
  703. #endif /* !_ATLSTL_NO_NAMESPACE */
  704. /* ////////////////////////////////////////////////////////////////////// */
  705. #endif /* !ATLSTL_INCL_ATLSTL_STRING_HPP_CCOMBSTR_VENEER */
  706. /* ///////////////////////////// end of file //////////////////////////// */