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.

846 lines
24 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: winstl/conversion/char_conversions.hpp (originally MLStrCnv.h, ::SynesisStd)
  3. *
  4. * Purpose: Type conversions for Windows.
  5. *
  6. * Created: 31st May 2003
  7. * Updated: 14th June 2012
  8. *
  9. * Home: http://stlsoft.org/
  10. *
  11. * Copyright (c) 2003-2012, 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
  16. * met:
  17. *
  18. * - Redistributions of source code must retain the above copyright notice,
  19. * this list of conditions and the following disclaimer.
  20. * - Redistributions in binary form must reproduce the above copyright
  21. * notice, this list of conditions and the following disclaimer in the
  22. * documentation and/or other materials provided with the distribution.
  23. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the
  24. * names of any contributors may be used to endorse or promote products
  25. * derived from this software without specific prior written permission.
  26. *
  27. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  28. * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  29. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  30. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  31. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  32. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  33. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  34. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  35. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  36. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  37. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. * ////////////////////////////////////////////////////////////////////// */
  40. /** \file winstl/conversion/char_conversions.hpp
  41. *
  42. * \brief [C++ only] Definition of the winstl::multibyte2wide and
  43. * winstl::wide2multibyte class templates
  44. * (\ref group__library__conversion "Conversion" Library).
  45. */
  46. #ifndef WINSTL_INCL_WINSTL_CONVERSION_HPP_CHAR_CONVERSIONS
  47. #define WINSTL_INCL_WINSTL_CONVERSION_HPP_CHAR_CONVERSIONS
  48. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  49. # define WINSTL_VER_WINSTL_CONVERSION_HPP_CHAR_CONVERSIONS_MAJOR 5
  50. # define WINSTL_VER_WINSTL_CONVERSION_HPP_CHAR_CONVERSIONS_MINOR 4
  51. # define WINSTL_VER_WINSTL_CONVERSION_HPP_CHAR_CONVERSIONS_REVISION 1
  52. # define WINSTL_VER_WINSTL_CONVERSION_HPP_CHAR_CONVERSIONS_EDIT 92
  53. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  54. /* /////////////////////////////////////////////////////////////////////////
  55. * Compatibility
  56. */
  57. /*
  58. [Incompatibilies-start]
  59. STLSOFT_COMPILER_IS_GCC: __GNUC__<3
  60. STLSOFT_COMPILER_IS_MSVC: _MSC_VER<1200
  61. [Incompatibilies-end]
  62. */
  63. /* /////////////////////////////////////////////////////////////////////////
  64. * Includes
  65. */
  66. #ifndef WINSTL_INCL_WINSTL_H_WINSTL
  67. # include <winstl/winstl.h>
  68. #endif /* !WINSTL_INCL_WINSTL_H_WINSTL */
  69. #if defined(STLSOFT_COMPILER_IS_GCC) && \
  70. __GNUC__ < 3
  71. # error winstl/conversion/char_conversions.hpp is not compatible with GNU C++ prior to 3.0
  72. #endif /* compiler */
  73. #if defined(STLSOFT_COMPILER_IS_MSVC) && \
  74. _MSC_VER < 1100
  75. # error winstl/conversion/char_conversions.hpp is not compatible with Visual C++ 5.0 or earlier
  76. #endif /* compiler */
  77. #ifndef WINSTL_INCL_WINSTL_MEMORY_HPP_PROCESSHEAP_ALLOCATOR
  78. # include <winstl/memory/processheap_allocator.hpp>
  79. #endif /* !WINSTL_INCL_WINSTL_MEMORY_HPP_PROCESSHEAP_ALLOCATOR */
  80. #ifndef STLSOFT_INCL_STLSOFT_SHIMS_ACCESS_HPP_STRING
  81. # include <stlsoft/shims/access/string.hpp>
  82. #endif /* !STLSOFT_INCL_STLSOFT_SHIMS_ACCESS_HPP_STRING */
  83. #ifndef WINSTL_INCL_WINSTL_SHIMS_ACCESS_HPP_STRING
  84. # include <winstl/shims/access/string.hpp>
  85. #endif /* !WINSTL_INCL_WINSTL_SHIMS_ACCESS_HPP_STRING */
  86. #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER
  87. # include <stlsoft/memory/auto_buffer.hpp>
  88. #endif /* !STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER */
  89. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  90. # ifndef WINSTL_INCL_WINSTL_ERROR_HPP_CONVERSION_ERROR
  91. # include <winstl/error/conversion_error.hpp>
  92. # endif /* !WINSTL_INCL_WINSTL_ERROR_HPP_CONVERSION_ERROR */
  93. # include <errno.h>
  94. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  95. #ifdef STLSOFT_UNITTEST
  96. # include <wchar.h>
  97. #endif /* STLSOFT_UNITTEST */
  98. /* ////////////////////////////////////////////////////////////////////// */
  99. #ifndef _WINSTL_NO_NAMESPACE
  100. # if defined(_STLSOFT_NO_NAMESPACE) || \
  101. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  102. /* There is no stlsoft namespace, so must define ::winstl */
  103. namespace winstl
  104. {
  105. # else
  106. /* Define stlsoft::winstl_project */
  107. namespace stlsoft
  108. {
  109. namespace winstl_project
  110. {
  111. # endif /* _STLSOFT_NO_NAMESPACE */
  112. #endif /* !_WINSTL_NO_NAMESPACE */
  113. /* /////////////////////////////////////////////////////////////////////////
  114. * Classes
  115. */
  116. /** Converts a multibyte (<code>char</code>-based) string to a wide
  117. * (<code>whar_t</code>-based) string.
  118. *
  119. * \ingroup group__library__conversion
  120. */
  121. template <ws_size_t CCH>
  122. class multibyte2wide
  123. : private auto_buffer_old<ws_char_w_t, processheap_allocator<ws_char_w_t>, CCH>
  124. {
  125. /// \name Member Types
  126. /// @{
  127. private:
  128. typedef auto_buffer_old<ws_char_w_t, processheap_allocator<ws_char_w_t>, CCH> parent_class_type;
  129. public:
  130. /// The character type
  131. typedef ws_char_w_t char_type;
  132. /// The alternate character type
  133. typedef ws_char_a_t alt_char_type;
  134. /// The size type
  135. typedef ss_typename_type_k parent_class_type::size_type size_type;
  136. /// The pointer type
  137. typedef ss_typename_type_k parent_class_type::pointer pointer;
  138. /// This type
  139. typedef multibyte2wide<CCH> class_type;
  140. /// @}
  141. /// \name Construction
  142. /// @{
  143. public:
  144. #ifdef STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
  145. template <ss_typename_param_k S>
  146. ss_explicit_k multibyte2wide(S const& s)
  147. #else
  148. ss_explicit_k multibyte2wide(alt_char_type const* s)
  149. #endif // STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
  150. : parent_class_type(stlsoft_ns_qual(c_str_len)(s) + 1)
  151. {
  152. prepare_(stlsoft_ns_qual(c_str_ptr_a)(s));
  153. }
  154. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  155. # ifdef STLSOFT_COMPILER_IS_GCC
  156. multibyte2wide(class_type const& s)
  157. : parent_class_type(s.size() + 1)
  158. {
  159. char_type* p = &static_cast<parent_class_type&>(*this)[0];
  160. ::memcpy(p, s, sizeof(char_type) * (1u + s.size()));
  161. STLSOFT_ASSERT('\0' == (*this)[s.size()]);
  162. }
  163. # endif /* compiler */
  164. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  165. #ifdef STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
  166. template <ss_typename_param_k S>
  167. multibyte2wide(S const& s, size_type cch)
  168. #else
  169. multibyte2wide(alt_char_type const* s, size_type cch)
  170. #endif // STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
  171. : parent_class_type(cch + 1)
  172. {
  173. prepare_(stlsoft_ns_qual(c_str_ptr_a)(s));
  174. }
  175. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  176. /// @}
  177. /// \name Implementation
  178. /// @{
  179. private:
  180. void prepare_(alt_char_type const* s)
  181. {
  182. const size_type size = parent_class_type::size();
  183. const pointer data = parent_class_type::data();
  184. // If the auto_buffer failed to allocate the required memory, and
  185. // we're not in an exception-environment, then size() will be zero
  186. if(0 == size)
  187. {
  188. // Since we know that auto_buffer's parameterising size must
  189. // always be greater that 0, then
  190. data[0] = '\0';
  191. }
  192. else
  193. {
  194. // Note: cannot use -1 for length, since s might be a type that
  195. // could change length
  196. if(0 == ::MultiByteToWideChar(0, 0, s, static_cast<int>(size), data, static_cast<int>(size)))
  197. {
  198. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  199. STLSOFT_THROW_X(conversion_error("failed to convert multibyte string to wide string", ::GetLastError()));
  200. #else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
  201. data[0] = '\0';
  202. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  203. }
  204. else
  205. {
  206. data[size - 1] = '\0';
  207. }
  208. }
  209. }
  210. /// @}
  211. /// \name Accessors
  212. /// @{
  213. public:
  214. char_type const* data() const
  215. {
  216. return parent_class_type::data();
  217. }
  218. char_type const* c_str() const
  219. {
  220. return parent_class_type::data();
  221. }
  222. size_type size() const
  223. {
  224. size_type n = parent_class_type::size();
  225. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  226. WINSTL_ASSERT(0 != n);
  227. #else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
  228. if(0 == n)
  229. {
  230. return 0;
  231. }
  232. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  233. return n - 1;
  234. }
  235. /// @}
  236. /// \name Operators
  237. /// @{
  238. public:
  239. operator char_type const* () const
  240. {
  241. return parent_class_type::data();
  242. }
  243. /// @}
  244. /// \name Not to be implemented
  245. /// @{
  246. private:
  247. #ifndef STLSOFT_COMPILER_IS_GCC
  248. multibyte2wide(class_type const&);
  249. #endif /* compiler */
  250. multibyte2wide& operator =(class_type const&);
  251. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  252. /// @}
  253. };
  254. /** Converts a wide (<code>whar_t</code>-based) string to a
  255. * multibyte (<code>char</code>-based) string.
  256. *
  257. * \ingroup group__library__conversion
  258. */
  259. template <ws_size_t CCH>
  260. class wide2multibyte
  261. : private auto_buffer_old<ws_char_a_t, processheap_allocator<ws_char_a_t>, CCH>
  262. {
  263. /// \name Member Types
  264. /// @{
  265. private:
  266. typedef auto_buffer_old<ws_char_a_t, processheap_allocator<ws_char_a_t>, CCH> parent_class_type;
  267. public:
  268. /// The character type
  269. typedef ws_char_a_t char_type;
  270. /// The alternate character type
  271. typedef ws_char_w_t alt_char_type;
  272. /// The size type
  273. typedef ss_typename_type_k parent_class_type::size_type size_type;
  274. /// The pointer type
  275. typedef ss_typename_type_k parent_class_type::pointer pointer;
  276. /// This type
  277. typedef wide2multibyte<CCH> class_type;
  278. /// @}
  279. /// \name Construction
  280. /// @{
  281. public:
  282. #ifdef STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
  283. template <ss_typename_param_k S>
  284. ss_explicit_k wide2multibyte(S const& s)
  285. #else
  286. ss_explicit_k wide2multibyte(alt_char_type const* s)
  287. #endif // STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
  288. : parent_class_type(stlsoft_ns_qual(c_str_len)(s) + 1)
  289. {
  290. prepare_(stlsoft_ns_qual(c_str_ptr_w)(s));
  291. }
  292. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  293. # ifdef STLSOFT_COMPILER_IS_GCC
  294. wide2multibyte(class_type const& s)
  295. : parent_class_type(s.size() + 1)
  296. {
  297. char_type* p = &static_cast<parent_class_type&>(*this)[0];
  298. ::memcpy(p, s, sizeof(char_type) * (1u + s.size()));
  299. STLSOFT_ASSERT('\0' == (*this)[s.size()]);
  300. }
  301. # endif /* compiler */
  302. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  303. #ifdef STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
  304. template <ss_typename_param_k S>
  305. ss_explicit_k wide2multibyte(S const& s, size_type cch)
  306. #else
  307. ss_explicit_k wide2multibyte(alt_char_type const* s, size_type cch)
  308. #endif // STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
  309. : parent_class_type(cch + 1)
  310. {
  311. prepare_(stlsoft_ns_qual(c_str_ptr_w)(s));
  312. }
  313. /// @}
  314. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  315. /// \name Implementation
  316. /// @{
  317. private:
  318. void prepare_(alt_char_type const* s)
  319. {
  320. const size_type size = parent_class_type::size();
  321. const pointer data = parent_class_type::data();
  322. // If the auto_buffer failed to allocate the required memory, and
  323. // we're not in an exception-environment, then size() will be zero
  324. if(0 == size)
  325. {
  326. // Since we know that auto_buffer's parameterising size must
  327. // always be greater that 0, then
  328. data[0] = '\0';
  329. }
  330. else
  331. {
  332. // Note: cannot use -1 for length, since s might be a type that
  333. // could change length
  334. if(0 == ::WideCharToMultiByte(0, 0, s, static_cast<int>(size), data, static_cast<int>(size), NULL, NULL))
  335. {
  336. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  337. STLSOFT_THROW_X(conversion_error("failed to convert multibyte string to wide string", ::GetLastError()));
  338. #else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
  339. data[0] = '\0';
  340. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  341. }
  342. else
  343. {
  344. data[size - 1] = '\0';
  345. }
  346. }
  347. }
  348. /// @}
  349. /// \name Accessors
  350. /// @{
  351. public:
  352. char_type const* data() const
  353. {
  354. return parent_class_type::data();
  355. }
  356. char_type const* c_str() const
  357. {
  358. return parent_class_type::data();
  359. }
  360. size_type size() const
  361. {
  362. size_type n = parent_class_type::size();
  363. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  364. WINSTL_ASSERT(0 != n);
  365. #else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
  366. if(0 == n)
  367. {
  368. return 0;
  369. }
  370. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  371. return n - 1;
  372. }
  373. /// @}
  374. /// \name Operators
  375. /// @{
  376. public:
  377. operator char_type const* () const
  378. {
  379. return parent_class_type::data();
  380. }
  381. /// @}
  382. // Not to be implemented
  383. private:
  384. #ifndef STLSOFT_COMPILER_IS_GCC
  385. wide2multibyte(class_type const&);
  386. #endif /* compiler */
  387. wide2multibyte& operator =(class_type const&);
  388. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  389. };
  390. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  391. template< ss_typename_param_k S
  392. , ss_typename_param_k C
  393. >
  394. struct encoding2encoding_traits
  395. {
  396. static C const* elicit_ccs(S const& s)
  397. {
  398. return s.c_str();
  399. }
  400. };
  401. #ifdef __ATLBASE_H__
  402. STLSOFT_TEMPLATE_SPECIALISATION
  403. inline
  404. wchar_t const*
  405. encoding2encoding_traits< ::ATL::CComBSTR, wchar_t>::elicit_ccs( ::ATL::CComBSTR const& s)
  406. {
  407. return s.m_str;
  408. }
  409. #endif /* __ATLBASE_H__ */
  410. template <ss_typename_param_k C>
  411. class encoding2encoding
  412. {
  413. public:
  414. encoding2encoding(C const* s)
  415. : m_s(s)
  416. {}
  417. encoding2encoding(C *s)
  418. : m_s(s)
  419. {}
  420. template <ss_typename_param_k S>
  421. encoding2encoding(S const& s)
  422. : m_s(encoding2encoding_traits<S, C>::elicit_ccs(s))
  423. {}
  424. public:
  425. C const* c_str() const
  426. {
  427. return m_s;
  428. }
  429. operator C const* () const
  430. {
  431. return m_s;
  432. }
  433. private:
  434. C const* m_s;
  435. };
  436. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  437. /* ////////////////////////////////////////////////////////////////////// */
  438. /** Type that converts a multibyte string to a wide string.
  439. *
  440. * \ingroup group__library__conversion
  441. */
  442. typedef multibyte2wide<256> m2w;
  443. /** Type that converts a wide string to a multibyte string.
  444. *
  445. * \ingroup group__library__conversion
  446. */
  447. typedef wide2multibyte<256> w2m;
  448. /** [Deprecated] Type that converts a multibyte string to a wide string.
  449. *
  450. * \ingroup group__library__conversion
  451. *
  452. * \deprecated This name is deprecated in favour of winstl::m2w
  453. */
  454. typedef multibyte2wide<256> a2w;
  455. /** [Deprecated] Type that converts a wide string to a multibyte string.
  456. *
  457. * \ingroup group__library__conversion
  458. *
  459. * \deprecated This name is deprecated in favour of winstl::w2m
  460. */
  461. typedef wide2multibyte<256> w2a;
  462. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  463. # if defined(UNICODE)
  464. typedef encoding2encoding<ws_char_w_t> t2w;
  465. typedef encoding2encoding<ws_char_w_t> w2t;
  466. typedef w2m t2m;
  467. typedef m2w m2t;
  468. typedef w2a t2a;
  469. typedef a2w a2t;
  470. # else /* ? UNICODE */
  471. typedef encoding2encoding<ws_char_a_t> t2a;
  472. typedef encoding2encoding<ws_char_a_t> a2t;
  473. typedef m2w t2w;
  474. typedef w2m w2t;
  475. typedef a2w t2w;
  476. typedef w2a w2t;
  477. # endif /* UNICODE */
  478. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  479. /* /////////////////////////////////////////////////////////////////////////
  480. * Shims
  481. */
  482. /** \brief \ref group__concept__shim__string_access__c_str_ptr_null for winstl::multibyte2wide
  483. *
  484. * \ingroup group__concept__shim__string_access
  485. */
  486. template< ws_size_t CCH
  487. >
  488. inline ws_char_w_t const* c_str_ptr_null(winstl_ns_qual(multibyte2wide)<CCH> const& b)
  489. {
  490. return stlsoft_ns_qual(c_str_ptr_null)(b.c_str());
  491. }
  492. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  493. template< ws_size_t CCH
  494. >
  495. inline ws_char_w_t const* c_str_ptr_null_w(winstl_ns_qual(multibyte2wide)<CCH> const& b)
  496. {
  497. return stlsoft_ns_qual(c_str_ptr_null)(b.c_str());
  498. }
  499. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  500. /** \brief \ref group__concept__shim__string_access__c_str_ptr for winstl::multibyte2wide
  501. *
  502. * \ingroup group__concept__shim__string_access
  503. */
  504. template< ws_size_t CCH
  505. >
  506. inline ws_char_w_t const* c_str_ptr(winstl_ns_qual(multibyte2wide)<CCH> const& b)
  507. {
  508. return b.c_str();
  509. }
  510. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  511. template< ws_size_t CCH
  512. >
  513. inline ws_char_w_t const* c_str_ptr_w(winstl_ns_qual(multibyte2wide)<CCH> const& b)
  514. {
  515. return b.c_str();
  516. }
  517. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  518. /** \brief \ref group__concept__shim__string_access__c_str_data for winstl::multibyte2wide
  519. *
  520. * \ingroup group__concept__shim__string_access
  521. */
  522. template< ws_size_t CCH
  523. >
  524. inline ws_char_w_t const* c_str_data(winstl_ns_qual(multibyte2wide)<CCH> const& b)
  525. {
  526. return b.data();
  527. }
  528. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  529. template< ws_size_t CCH
  530. >
  531. inline ws_char_w_t const* c_str_data_w(winstl_ns_qual(multibyte2wide)<CCH> const& b)
  532. {
  533. return b.data();
  534. }
  535. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  536. /** \brief \ref group__concept__shim__string_access__c_str_len for winstl::multibyte2wide
  537. *
  538. * \ingroup group__concept__shim__string_access
  539. */
  540. template< ws_size_t CCH
  541. >
  542. inline ws_size_t c_str_len(winstl_ns_qual(multibyte2wide)<CCH> const& b)
  543. {
  544. return b.size();
  545. }
  546. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  547. template< ws_size_t CCH
  548. >
  549. inline ws_size_t c_str_len_w(winstl_ns_qual(multibyte2wide)<CCH> const& b)
  550. {
  551. return b.size();
  552. }
  553. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  554. /** \brief \ref group__concept__shim__string_access__c_str_ptr_null for winstl::wide2multibyte
  555. *
  556. * \ingroup group__concept__shim__string_access
  557. */
  558. template< ws_size_t CCH
  559. >
  560. inline ws_char_a_t const* c_str_ptr_null(winstl_ns_qual(wide2multibyte)<CCH> const& b)
  561. {
  562. return stlsoft_ns_qual(c_str_ptr_null)(b.c_str());
  563. }
  564. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  565. template< ws_size_t CCH
  566. >
  567. inline ws_char_a_t const* c_str_ptr_null_a(winstl_ns_qual(wide2multibyte)<CCH> const& b)
  568. {
  569. return stlsoft_ns_qual(c_str_ptr_null)(b.c_str());
  570. }
  571. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  572. /** \brief \ref group__concept__shim__string_access__c_str_ptr for winstl::wide2multibyte
  573. *
  574. * \ingroup group__concept__shim__string_access
  575. */
  576. template< ws_size_t CCH
  577. >
  578. inline ws_char_a_t const* c_str_ptr(winstl_ns_qual(wide2multibyte)<CCH> const& b)
  579. {
  580. return b.c_str();
  581. }
  582. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  583. template< ws_size_t CCH
  584. >
  585. inline ws_char_a_t const* c_str_ptr_a(winstl_ns_qual(wide2multibyte)<CCH> const& b)
  586. {
  587. return b.c_str();
  588. }
  589. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  590. /** \brief \ref group__concept__shim__string_access__c_str_data for winstl::wide2multibyte
  591. *
  592. * \ingroup group__concept__shim__string_access
  593. */
  594. template< ws_size_t CCH
  595. >
  596. inline ws_char_a_t const* c_str_data(winstl_ns_qual(wide2multibyte)<CCH> const& b)
  597. {
  598. return b.data();
  599. }
  600. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  601. template< ws_size_t CCH
  602. >
  603. inline ws_char_a_t const* c_str_data_a(winstl_ns_qual(wide2multibyte)<CCH> const& b)
  604. {
  605. return b.data();
  606. }
  607. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  608. /** \brief \ref group__concept__shim__string_access__c_str_len for winstl::wide2multibyte
  609. *
  610. * \ingroup group__concept__shim__string_access
  611. */
  612. template< ws_size_t CCH
  613. >
  614. inline ws_size_t c_str_len(winstl_ns_qual(wide2multibyte)<CCH> const& b)
  615. {
  616. return b.size();
  617. }
  618. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  619. template< ws_size_t CCH
  620. >
  621. inline ws_size_t c_str_len_a(winstl_ns_qual(wide2multibyte)<CCH> const& b)
  622. {
  623. return b.size();
  624. }
  625. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  626. /** \brief \ref group__concept__shim__stream_insertion "stream insertion shim" for winstl::multibyte2wide
  627. *
  628. * \ingroup group__concept__shim__stream_insertion
  629. */
  630. template< ss_typename_param_k S
  631. , ws_size_t CCH
  632. >
  633. inline S& operator <<(S& s, winstl_ns_qual(multibyte2wide)<CCH> const& b)
  634. {
  635. s << b.c_str();
  636. return s;
  637. }
  638. /** \brief \ref group__concept__shim__stream_insertion "stream insertion shim" for winstl::wide2multibyte
  639. *
  640. * \ingroup group__concept__shim__stream_insertion
  641. */
  642. template< ss_typename_param_k S
  643. , ws_size_t CCH
  644. >
  645. inline S& operator <<(S& s, winstl_ns_qual(wide2multibyte)<CCH> const& b)
  646. {
  647. s << b.c_str();
  648. return s;
  649. }
  650. ////////////////////////////////////////////////////////////////////////////
  651. // Unit-testing
  652. #ifdef STLSOFT_UNITTEST
  653. # include "./unittest/char_conversions_unittest_.h"
  654. #endif /* STLSOFT_UNITTEST */
  655. /* ////////////////////////////////////////////////////////////////////// */
  656. #ifndef _WINSTL_NO_NAMESPACE
  657. # if defined(_STLSOFT_NO_NAMESPACE) || \
  658. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  659. } // namespace winstl
  660. # else
  661. } // namespace winstl_project
  662. } // namespace stlsoft
  663. # endif /* _STLSOFT_NO_NAMESPACE */
  664. #endif /* !_WINSTL_NO_NAMESPACE */
  665. /* /////////////////////////////////////////////////////////////////////////
  666. * Namespace
  667. *
  668. * The string access shims exist either in the stlsoft namespace, or in the
  669. * global namespace. This is required by the lookup rules.
  670. *
  671. */
  672. #ifndef _WINSTL_NO_NAMESPACE
  673. # if !defined(_STLSOFT_NO_NAMESPACE) && \
  674. !defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  675. namespace stlsoft
  676. {
  677. # else /* ? _STLSOFT_NO_NAMESPACE */
  678. /* There is no stlsoft namespace, so must define in the global namespace */
  679. # endif /* !_STLSOFT_NO_NAMESPACE */
  680. using ::winstl::c_str_data;
  681. using ::winstl::c_str_data_a;
  682. using ::winstl::c_str_data_w;
  683. using ::winstl::c_str_len;
  684. using ::winstl::c_str_len_a;
  685. using ::winstl::c_str_len_w;
  686. using ::winstl::c_str_ptr;
  687. using ::winstl::c_str_ptr_a;
  688. using ::winstl::c_str_ptr_w;
  689. using ::winstl::c_str_ptr_null;
  690. using ::winstl::c_str_ptr_null_a;
  691. using ::winstl::c_str_ptr_null_w;
  692. # if !defined(_STLSOFT_NO_NAMESPACE) && \
  693. !defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  694. } // namespace stlsoft
  695. # else /* ? _STLSOFT_NO_NAMESPACE */
  696. /* There is no stlsoft namespace, so must define in the global namespace */
  697. # endif /* !_STLSOFT_NO_NAMESPACE */
  698. #endif /* !_WINSTL_NO_NAMESPACE */
  699. /* /////////////////////////////////////////////////////////////////////////
  700. * Global namespace shims
  701. */
  702. /* This defines stream inserter shim function templates for the converters
  703. * for use with the Visual C++ <7.1 standard library.
  704. */
  705. #if defined(STLSOFT_CF_STD_LIBRARY_IS_DINKUMWARE_VC) && \
  706. STLSOFT_CF_STD_LIBRARY_DINKUMWARE_VC_VERSION < STLSOFT_CF_DINKUMWARE_VC_VERSION_7_1
  707. # include <iosfwd>
  708. template <winstl_ns_qual(ws_size_t) CCH>
  709. inline winstl_ns_qual_std(basic_ostream)<char>& operator <<(winstl_ns_qual_std(basic_ostream)<char> &stm, winstl_ns_qual(wide2multibyte)<CCH> const& b)
  710. {
  711. return stm << b.c_str();
  712. }
  713. template <winstl_ns_qual(ws_size_t) CCH>
  714. inline winstl_ns_qual_std(basic_ostream)<wchar_t>& operator <<(winstl_ns_qual_std(basic_ostream)<wchar_t> &stm, winstl_ns_qual(multibyte2wide)<CCH> const& b)
  715. {
  716. return stm << b.c_str();
  717. }
  718. #endif /* library */
  719. /* ////////////////////////////////////////////////////////////////////// */
  720. #endif /* WINSTL_INCL_WINSTL_CONVERSION_HPP_CHAR_CONVERSIONS */
  721. /* ///////////////////////////// end of file //////////////////////////// */