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.

771 lines
22 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: stlsoft/conversion/char_conversions.hpp (originally MLStrCnv.h, ::SynesisStd)
  3. *
  4. * Purpose: Character-encoding scheme interconversion components.
  5. *
  6. * Created: 31st May 2003
  7. * Updated: 29th January 2011
  8. *
  9. * Home: http://stlsoft.org/
  10. *
  11. * Copyright (c) 2003-2011, 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 stlsoft/conversion/char_conversions.hpp
  40. *
  41. * \brief [C++ only] Definition of the stlsoft::multibyte2wide and
  42. * stlsoft::wide2multibyte class templates
  43. * (\ref group__library__conversion "Conversion" Library).
  44. */
  45. #ifndef STLSOFT_INCL_STLSOFT_CONVERSION_HPP_CHAR_CONVERSIONS
  46. #define STLSOFT_INCL_STLSOFT_CONVERSION_HPP_CHAR_CONVERSIONS
  47. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  48. # define STLSOFT_VER_STLSOFT_CONVERSION_HPP_CHAR_CONVERSIONS_MAJOR 5
  49. # define STLSOFT_VER_STLSOFT_CONVERSION_HPP_CHAR_CONVERSIONS_MINOR 2
  50. # define STLSOFT_VER_STLSOFT_CONVERSION_HPP_CHAR_CONVERSIONS_REVISION 1
  51. # define STLSOFT_VER_STLSOFT_CONVERSION_HPP_CHAR_CONVERSIONS_EDIT 95
  52. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  53. /* /////////////////////////////////////////////////////////////////////////
  54. * Compatibility
  55. */
  56. /*
  57. [Incompatibilies-start]
  58. STLSOFT_COMPILER_IS_GCC: __GNUC__<3
  59. STLSOFT_COMPILER_IS_MSVC: _MSC_VER<1200
  60. [Incompatibilies-end]
  61. */
  62. /* /////////////////////////////////////////////////////////////////////////
  63. * Includes
  64. */
  65. #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
  66. # include <stlsoft/stlsoft.h>
  67. #endif /* !STLSOFT_INCL_STLSOFT_H_STLSOFT */
  68. #if defined(STLSOFT_COMPILER_IS_GCC) && \
  69. __GNUC__ < 3
  70. # error stlsoft/conversion/char_conversions.hpp is not compatible with GNU C++ prior to 3.0
  71. #endif /* compiler */
  72. #if defined(STLSOFT_COMPILER_IS_MSVC) && \
  73. _MSC_VER < 1100
  74. # error stlsoft/conversion/char_conversions.hpp is not compatible with Visual C++ 5.0 or earlier
  75. #endif /* compiler */
  76. #ifndef STLSOFT_INCL_STLSOFT_SHIMS_ACCESS_HPP_STRING
  77. # include <stlsoft/shims/access/string.hpp>
  78. #endif /* !STLSOFT_INCL_STLSOFT_SHIMS_ACCESS_HPP_STRING */
  79. #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER
  80. # include <stlsoft/memory/auto_buffer.hpp>
  81. #endif /* !STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER */
  82. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  83. # ifndef STLSOFT_INCL_STLSOFT_ERROR_HPP_CONVERSION_ERROR
  84. # include <stlsoft/error/conversion_error.hpp>
  85. # endif /* !STLSOFT_INCL_STLSOFT_ERROR_HPP_CONVERSION_ERROR */
  86. # include <errno.h>
  87. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  88. #ifndef STLSOFT_INCL_STLSOFT_INTERNAL_H_SAFESTR
  89. # include <stlsoft/internal/safestr.h>
  90. #endif /* !STLSOFT_INCL_STLSOFT_INTERNAL_H_SAFESTR */
  91. #ifdef STLSOFT_UNITTEST
  92. # include <wchar.h>
  93. #endif /* STLSOFT_UNITTEST */
  94. /* /////////////////////////////////////////////////////////////////////////
  95. * Namespace
  96. */
  97. #ifndef _STLSOFT_NO_NAMESPACE
  98. namespace stlsoft
  99. {
  100. #endif /* _STLSOFT_NO_NAMESPACE */
  101. /* /////////////////////////////////////////////////////////////////////////
  102. * Classes
  103. */
  104. /** \brief Converts a multibyte (<code>char</code>-based) string to a wide
  105. * (<code>whar_t</code>-based) string.
  106. *
  107. * \ingroup group__library__conversion
  108. */
  109. template <ss_size_t CCH>
  110. class multibyte2wide
  111. : public auto_buffer<ss_char_w_t, CCH>
  112. {
  113. /// \name Member Types
  114. /// @{
  115. private:
  116. typedef auto_buffer<ss_char_w_t, CCH> parent_class_type;
  117. public:
  118. /// \brief The character type
  119. typedef ss_char_w_t char_type;
  120. /// \brief The alternate character type
  121. typedef ss_char_a_t alt_char_type;
  122. /// \brief The size type
  123. typedef ss_typename_type_k parent_class_type::size_type size_type;
  124. /// \brief The pointer type
  125. typedef ss_typename_type_k parent_class_type::pointer pointer;
  126. /// @}
  127. /// \name Construction
  128. /// @{
  129. public:
  130. #ifdef STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
  131. template <ss_typename_param_k S>
  132. ss_explicit_k multibyte2wide(S const& s)
  133. #else /* ? STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT */
  134. ss_explicit_k multibyte2wide(alt_char_type const* s)
  135. #endif /* STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT */
  136. : parent_class_type(calc_length_(s) + 1)
  137. {
  138. prepare_(stlsoft_ns_qual(c_str_ptr_a)(s));
  139. }
  140. #ifdef STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
  141. template <ss_typename_param_k S>
  142. multibyte2wide(S const& s, size_type cch)
  143. #else
  144. multibyte2wide(alt_char_type const* s, size_type cch)
  145. #endif // STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
  146. : parent_class_type(cch + 1)
  147. {
  148. prepare_(stlsoft_ns_qual(c_str_data_a)(s), cch);
  149. }
  150. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  151. /// @}
  152. /// \name Implementation
  153. /// @{
  154. private:
  155. template <ss_typename_param_k S>
  156. static size_type calc_length_(S const& s)
  157. {
  158. return stlsoft_ns_qual(c_str_len_a)(s);
  159. }
  160. void prepare_(alt_char_type const* s)
  161. {
  162. prepare_(s, parent_class_type::size() - 1);
  163. }
  164. void prepare_(alt_char_type const* s, size_type size)
  165. {
  166. const pointer data = parent_class_type::data();
  167. // If the auto_buffer failed to allocate the required memory, and
  168. // we're not in an exception-environment, then size() will be zero
  169. if(0 == size)
  170. {
  171. // Since we know that auto_buffer's parameterising size must
  172. // always be greater that 0, then
  173. data[0] = '\0';
  174. }
  175. else
  176. {
  177. int err;
  178. #ifdef STLSOFT_USING_SAFE_STR_FUNCTIONS
  179. ss_size_t numConverted;
  180. err = ::mbstowcs_s(&numConverted, data, size + 1, s, size);
  181. if(0 != err)
  182. {
  183. #else /* ? STLSOFT_USING_SAFE_STR_FUNCTIONS */
  184. if(static_cast<ss_size_t>(-1) == ::mbstowcs(data, s, size))
  185. {
  186. err = errno;
  187. #endif /* STLSOFT_USING_SAFE_STR_FUNCTIONS */
  188. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  189. STLSOFT_THROW_X(conversion_error("failed to convert multibyte string to wide string", err));
  190. #else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
  191. data[0] = '\0';
  192. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  193. } // '}'
  194. else
  195. {
  196. data[size] = '\0';
  197. }
  198. }
  199. }
  200. /// @}
  201. /// \name Accessors
  202. /// @{
  203. public:
  204. char_type const* data() const
  205. {
  206. return parent_class_type::data();
  207. }
  208. char_type const* c_str() const
  209. {
  210. return parent_class_type::data();
  211. }
  212. size_type size() const
  213. {
  214. size_type n = parent_class_type::size();
  215. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  216. STLSOFT_ASSERT(0 != n);
  217. #else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
  218. if(0 == n)
  219. {
  220. return 0;
  221. }
  222. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  223. return n - 1;
  224. }
  225. /// @}
  226. /// \name Operators
  227. /// @{
  228. public:
  229. operator char_type const* () const
  230. {
  231. return parent_class_type::data();
  232. }
  233. /// @}
  234. /// \name Not to be implemented
  235. /// @{
  236. private:
  237. # if defined(STLSOFT_COMPILER_IS_GCC)
  238. public:
  239. multibyte2wide(multibyte2wide const& rhs)
  240. : parent_class_type(rhs.parent_class_type::size())
  241. {
  242. ::memcpy(this->parent_class_type::data(), rhs.parent_class_type::data(), this->parent_class_type::size());
  243. }
  244. private:
  245. # else /* compiler */
  246. multibyte2wide(multibyte2wide const&);
  247. # endif /* compiler */
  248. multibyte2wide& operator =(multibyte2wide const&);
  249. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  250. /// @}
  251. };
  252. /** \brief Converts a wide (<code>whar_t</code>-based) string to a
  253. * multibyte (<code>char</code>-based) string.
  254. *
  255. * \ingroup group__library__conversion
  256. */
  257. template <ss_size_t CCH>
  258. class wide2multibyte
  259. : public auto_buffer<ss_char_a_t, CCH>
  260. {
  261. /// \name Member Types
  262. /// @{
  263. private:
  264. typedef auto_buffer<ss_char_a_t, CCH> parent_class_type;
  265. public:
  266. /// \brief The character type
  267. typedef ss_char_a_t char_type;
  268. /// \brief The alternate character type
  269. typedef ss_char_w_t alt_char_type;
  270. /// \brief The size type
  271. typedef ss_typename_type_k parent_class_type::size_type size_type;
  272. /// \brief The pointer type
  273. typedef ss_typename_type_k parent_class_type::pointer pointer;
  274. /// @}
  275. /// \name Construction
  276. /// @{
  277. public:
  278. #ifdef STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
  279. template <ss_typename_param_k S>
  280. ss_explicit_k wide2multibyte(S const& s)
  281. #else
  282. ss_explicit_k wide2multibyte(alt_char_type const* s)
  283. #endif // STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
  284. : parent_class_type(stlsoft_ns_qual(c_str_len)(s) + 1)
  285. {
  286. prepare_(stlsoft_ns_qual(c_str_ptr_w)(s));
  287. }
  288. #ifdef STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
  289. template <ss_typename_param_k S>
  290. ss_explicit_k wide2multibyte(S const& s, size_type cch)
  291. #else
  292. ss_explicit_k wide2multibyte(alt_char_type const* s, size_type cch)
  293. #endif // STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
  294. : parent_class_type(cch + 1)
  295. {
  296. prepare_(stlsoft_ns_qual(c_str_data_w)(s), cch);
  297. }
  298. /// @}
  299. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  300. // Implementation
  301. private:
  302. void prepare_(alt_char_type const* s)
  303. {
  304. prepare_(s, parent_class_type::size() - 1);
  305. }
  306. void prepare_(alt_char_type const* s, size_type size)
  307. {
  308. const pointer data = parent_class_type::data();
  309. // If the auto_buffer failed to allocate the required memory, and
  310. // we're not in an exception-environment, then size() will be zero
  311. if(0 == size)
  312. {
  313. // Since we know that auto_buffer's parameterising size must
  314. // always be greater that 0, then
  315. data[0] = '\0';
  316. }
  317. else
  318. {
  319. int err;
  320. #ifdef STLSOFT_USING_SAFE_STR_FUNCTIONS
  321. ss_size_t numConverted;
  322. err = ::wcstombs_s(&numConverted, data, size + 1, s, size);
  323. if(0 != err)
  324. {
  325. #else /* ? STLSOFT_USING_SAFE_STR_FUNCTIONS */
  326. if(static_cast<ss_size_t>(-1) == ::wcstombs(data, s, size))
  327. {
  328. err = errno;
  329. #endif /* STLSOFT_USING_SAFE_STR_FUNCTIONS */
  330. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  331. STLSOFT_THROW_X(conversion_error("failed to convert wide string to multibyte string", err));
  332. #else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
  333. data[0] = '\0';
  334. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  335. }
  336. else
  337. {
  338. data[size] = '\0';
  339. }
  340. }
  341. }
  342. /// \name Accessors
  343. /// @{
  344. public:
  345. char_type const* data() const
  346. {
  347. return parent_class_type::data();
  348. }
  349. char_type const* c_str() const
  350. {
  351. return parent_class_type::data();
  352. }
  353. size_type size() const
  354. {
  355. size_type n = parent_class_type::size();
  356. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  357. STLSOFT_ASSERT(0 != n);
  358. #else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
  359. if(0 == n)
  360. {
  361. return 0;
  362. }
  363. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  364. return n - 1;
  365. }
  366. /// @}
  367. /// \name Operators
  368. /// @{
  369. public:
  370. operator char_type const* () const
  371. {
  372. return parent_class_type::data();
  373. }
  374. /// @}
  375. /// \name Not to be implemented
  376. /// @{
  377. private:
  378. # if defined(STLSOFT_COMPILER_IS_GCC)
  379. public:
  380. wide2multibyte(wide2multibyte const& rhs)
  381. : parent_class_type(rhs.parent_class_type::size())
  382. {
  383. ::memcpy(this->parent_class_type::data(), rhs.parent_class_type::data(), this->parent_class_type::size());
  384. }
  385. private:
  386. # else /* compiler */
  387. wide2multibyte(wide2multibyte const&);
  388. # endif /* compiler */
  389. wide2multibyte& operator =(wide2multibyte const&);
  390. /// @}
  391. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  392. };
  393. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  394. template <ss_typename_param_k C>
  395. class encoding2encoding
  396. {
  397. public:
  398. encoding2encoding(C const* s)
  399. : m_s(s)
  400. {}
  401. encoding2encoding(C *s)
  402. : m_s(s)
  403. {}
  404. template <ss_typename_param_k S>
  405. encoding2encoding(S const& s)
  406. : m_s(s.c_str())
  407. {}
  408. public:
  409. C const* c_str() const
  410. {
  411. return m_s;
  412. }
  413. operator C const* () const
  414. {
  415. return m_s;
  416. }
  417. private:
  418. C const* m_s;
  419. };
  420. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  421. /* ////////////////////////////////////////////////////////////////////// */
  422. /** \brief Type that converts a multibyte string to a wide string.
  423. *
  424. * \ingroup group__library__conversion
  425. */
  426. typedef multibyte2wide<256> m2w;
  427. /** \brief Type that converts a wide string to a multibyte string.
  428. *
  429. * \ingroup group__library__conversion
  430. */
  431. typedef wide2multibyte<256> w2m;
  432. /** \brief [Deprecated] Type that converts a multibyte string to a wide string.
  433. *
  434. * \ingroup group__library__conversion
  435. *
  436. * \deprecated This name is deprecated in favour of stlsoft::m2w
  437. */
  438. typedef multibyte2wide<256> a2w;
  439. /** \brief [Deprecated] Type that converts a wide string to a multibyte string.
  440. *
  441. * \ingroup group__library__conversion
  442. *
  443. * \deprecated This name is deprecated in favour of stlsoft::w2m
  444. */
  445. typedef wide2multibyte<256> w2a;
  446. //#if defined(UNICODE)
  447. //typedef encoding2encoding<ss_char_w_t> t2w;
  448. //typedef encoding2encoding<ss_char_w_t> w2t;
  449. //typedef w2a t2a;
  450. //typedef a2w a2t;
  451. //#else /* ? UNICODE */
  452. //typedef encoding2encoding<ss_char_a_t> t2a;
  453. //typedef encoding2encoding<ss_char_a_t> a2t;
  454. //typedef a2w t2w;
  455. //typedef w2a w2t;
  456. //#endif /* UNICODE */
  457. /* /////////////////////////////////////////////////////////////////////////
  458. * Shims
  459. */
  460. /** \brief \ref group__concept__shim__string_access__c_str_ptr_null for stlsoft::multibyte2wide
  461. *
  462. * \ingroup group__concept__shim__string_access
  463. */
  464. template< ss_size_t CCH
  465. >
  466. inline ss_char_w_t const* c_str_ptr_null(stlsoft_ns_qual(multibyte2wide)<CCH> const& b)
  467. {
  468. return stlsoft_ns_qual(c_str_ptr_null)(b.c_str());
  469. }
  470. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  471. template< ss_size_t CCH
  472. >
  473. inline ss_char_w_t const* c_str_ptr_null_w(stlsoft_ns_qual(multibyte2wide)<CCH> const& b)
  474. {
  475. return stlsoft_ns_qual(c_str_ptr_null)(b.c_str());
  476. }
  477. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  478. /** \brief \ref group__concept__shim__string_access__c_str_ptr for stlsoft::multibyte2wide
  479. *
  480. * \ingroup group__concept__shim__string_access
  481. */
  482. template< ss_size_t CCH
  483. >
  484. inline ss_char_w_t const* c_str_ptr(stlsoft_ns_qual(multibyte2wide)<CCH> const& b)
  485. {
  486. return b.c_str();
  487. }
  488. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  489. template< ss_size_t CCH
  490. >
  491. inline ss_char_w_t const* c_str_ptr_w(stlsoft_ns_qual(multibyte2wide)<CCH> const& b)
  492. {
  493. return b.c_str();
  494. }
  495. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  496. /** \brief \ref group__concept__shim__string_access__c_str_data for stlsoft::multibyte2wide
  497. *
  498. * \ingroup group__concept__shim__string_access
  499. */
  500. template< ss_size_t CCH
  501. >
  502. inline ss_char_w_t const* c_str_data(stlsoft_ns_qual(multibyte2wide)<CCH> const& b)
  503. {
  504. return b.data();
  505. }
  506. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  507. template< ss_size_t CCH
  508. >
  509. inline ss_char_w_t const* c_str_data_w(stlsoft_ns_qual(multibyte2wide)<CCH> const& b)
  510. {
  511. return b.data();
  512. }
  513. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  514. /** \brief \ref group__concept__shim__string_access__c_str_len for stlsoft::multibyte2wide
  515. *
  516. * \ingroup group__concept__shim__string_access
  517. */
  518. template< ss_size_t CCH
  519. >
  520. inline ss_size_t c_str_len(stlsoft_ns_qual(multibyte2wide)<CCH> const& b)
  521. {
  522. return b.size();
  523. }
  524. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  525. template< ss_size_t CCH
  526. >
  527. inline ss_size_t c_str_len_w(stlsoft_ns_qual(multibyte2wide)<CCH> const& b)
  528. {
  529. return b.size();
  530. }
  531. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  532. /** \brief \ref group__concept__shim__string_access__c_str_ptr_null for stlsoft::wide2multibyte
  533. *
  534. * \ingroup group__concept__shim__string_access
  535. */
  536. template< ss_size_t CCH
  537. >
  538. inline ss_char_a_t const* c_str_ptr_null(stlsoft_ns_qual(wide2multibyte)<CCH> const& b)
  539. {
  540. return stlsoft_ns_qual(c_str_ptr_null)(b.c_str());
  541. }
  542. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  543. template< ss_size_t CCH
  544. >
  545. inline ss_char_a_t const* c_str_ptr_null_a(stlsoft_ns_qual(wide2multibyte)<CCH> const& b)
  546. {
  547. return stlsoft_ns_qual(c_str_ptr_null)(b.c_str());
  548. }
  549. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  550. /** \brief \ref group__concept__shim__string_access__c_str_ptr for stlsoft::wide2multibyte
  551. *
  552. * \ingroup group__concept__shim__string_access
  553. */
  554. template< ss_size_t CCH
  555. >
  556. inline ss_char_a_t const* c_str_ptr(stlsoft_ns_qual(wide2multibyte)<CCH> const& b)
  557. {
  558. return b.c_str();
  559. }
  560. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  561. template< ss_size_t CCH
  562. >
  563. inline ss_char_a_t const* c_str_ptr_a(stlsoft_ns_qual(wide2multibyte)<CCH> const& b)
  564. {
  565. return b.c_str();
  566. }
  567. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  568. /** \brief \ref group__concept__shim__string_access__c_str_data for stlsoft::wide2multibyte
  569. *
  570. * \ingroup group__concept__shim__string_access
  571. */
  572. template< ss_size_t CCH
  573. >
  574. inline ss_char_a_t const* c_str_data(stlsoft_ns_qual(wide2multibyte)<CCH> const& b)
  575. {
  576. return b.data();
  577. }
  578. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  579. template< ss_size_t CCH
  580. >
  581. inline ss_char_a_t const* c_str_data_a(stlsoft_ns_qual(wide2multibyte)<CCH> const& b)
  582. {
  583. return b.data();
  584. }
  585. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  586. /** \brief \ref group__concept__shim__string_access__c_str_len for stlsoft::wide2multibyte
  587. *
  588. * \ingroup group__concept__shim__string_access
  589. */
  590. template< ss_size_t CCH
  591. >
  592. inline ss_size_t c_str_len(stlsoft_ns_qual(wide2multibyte)<CCH> const& b)
  593. {
  594. return b.size();
  595. }
  596. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  597. template< ss_size_t CCH
  598. >
  599. inline ss_size_t c_str_len_a(stlsoft_ns_qual(wide2multibyte)<CCH> const& b)
  600. {
  601. return b.size();
  602. }
  603. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  604. /** \brief \ref group__concept__shim__stream_insertion "stream insertion shim" for stlsoft::multibyte2wide
  605. *
  606. * \ingroup group__concept__shim__stream_insertion
  607. */
  608. template< ss_typename_param_k S
  609. , ss_size_t CCH
  610. >
  611. inline S& operator <<(S& s, stlsoft_ns_qual(multibyte2wide)<CCH> const& b)
  612. {
  613. s << b.c_str();
  614. return s;
  615. }
  616. /** \brief \ref group__concept__shim__stream_insertion "stream insertion shim" for stlsoft::wide2multibyte
  617. *
  618. * \ingroup group__concept__shim__stream_insertion
  619. */
  620. template< ss_typename_param_k S
  621. , ss_size_t CCH
  622. >
  623. inline S& operator <<(S& s, stlsoft_ns_qual(wide2multibyte)<CCH> const& b)
  624. {
  625. s << b.c_str();
  626. return s;
  627. }
  628. ////////////////////////////////////////////////////////////////////////////
  629. // Unit-testing
  630. #ifdef STLSOFT_UNITTEST
  631. # include "./unittest/char_conversions_unittest_.h"
  632. #endif /* STLSOFT_UNITTEST */
  633. /* ////////////////////////////////////////////////////////////////////// */
  634. #ifndef _STLSOFT_NO_NAMESPACE
  635. } // namespace stlsoft
  636. #endif /* _STLSOFT_NO_NAMESPACE */
  637. /* /////////////////////////////////////////////////////////////////////////
  638. * Global namespace shims
  639. */
  640. /* This defines stream inserter shim function templates for the converters
  641. * for use with the Visual C++ <7.1 standard library.
  642. */
  643. #if defined(STLSOFT_CF_STD_LIBRARY_IS_DINKUMWARE_VC) && \
  644. STLSOFT_CF_STD_LIBRARY_DINKUMWARE_VC_VERSION < STLSOFT_CF_DINKUMWARE_VC_VERSION_7_1
  645. # include <iosfwd>
  646. template <stlsoft_ns_qual(ss_size_t) CCH>
  647. inline stlsoft_ns_qual_std(basic_ostream)<char>& operator <<(stlsoft_ns_qual_std(basic_ostream)<char> &stm, stlsoft_ns_qual(wide2multibyte)<CCH> const& b)
  648. {
  649. return stm << b.c_str();
  650. }
  651. template <stlsoft_ns_qual(ss_size_t) CCH>
  652. inline stlsoft_ns_qual_std(basic_ostream)<wchar_t>& operator <<(stlsoft_ns_qual_std(basic_ostream)<wchar_t> &stm, stlsoft_ns_qual(multibyte2wide)<CCH> const& b)
  653. {
  654. return stm << b.c_str();
  655. }
  656. #endif /* library */
  657. /* ////////////////////////////////////////////////////////////////////// */
  658. #endif /* !STLSOFT_INCL_STLSOFT_CONVERSION_HPP_CHAR_CONVERSIONS */
  659. /* ///////////////////////////// end of file //////////////////////////// */