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.

1123 lines
33 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: stlsoft/conversion/integer_to_string.hpp
  3. *
  4. * Purpose: Very efficient integer to string conversion functions.
  5. *
  6. * Created: 7th April 2002
  7. * Updated: 17th July 2012
  8. *
  9. * Home: http://stlsoft.org/
  10. *
  11. * Copyright (c) 2002-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 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/integer_to_string.hpp
  40. *
  41. * \brief [C++ only] Very efficient integer to string conversion functions
  42. * (\ref group__library__conversion "Conversion" Library).
  43. */
  44. #ifndef STLSOFT_INCL_STLSOFT_CONVERSION_HPP_INTEGER_TO_STRING
  45. #define STLSOFT_INCL_STLSOFT_CONVERSION_HPP_INTEGER_TO_STRING
  46. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  47. # define STLSOFT_VER_STLSOFT_CONVERSION_HPP_INTEGER_TO_STRING_MAJOR 4
  48. # define STLSOFT_VER_STLSOFT_CONVERSION_HPP_INTEGER_TO_STRING_MINOR 2
  49. # define STLSOFT_VER_STLSOFT_CONVERSION_HPP_INTEGER_TO_STRING_REVISION 1
  50. # define STLSOFT_VER_STLSOFT_CONVERSION_HPP_INTEGER_TO_STRING_EDIT 83
  51. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  52. /* /////////////////////////////////////////////////////////////////////////
  53. * Includes
  54. */
  55. #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
  56. # include <stlsoft/stlsoft.h>
  57. #endif /* !STLSOFT_INCL_STLSOFT_H_STLSOFT */
  58. #ifndef STLSOFT_CF_NEGATIVE_MODULUS_POSITIVE_GIVES_NEGATIVE_RESULT
  59. # ifndef STLSOFT_INCL_STLSOFT_UTIL_H_LIMIT_TRAITS
  60. # include <stlsoft/util/limit_traits.h>
  61. # endif /* !STLSOFT_INCL_STLSOFT_UTIL_H_LIMIT_TRAITS */
  62. # ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_SIGN_TRAITS
  63. # include <stlsoft/util/sign_traits.hpp>
  64. # endif /* !STLSOFT_INCL_STLSOFT_UTIL_HPP_SIGN_TRAITS */
  65. # ifndef STLSOFT_INCL_STLSOFT_META_HPP_IS_SAME_TYPE
  66. # include <stlsoft/meta/is_same_type.hpp>
  67. # endif /* !STLSOFT_INCL_STLSOFT_META_HPP_IS_SAME_TYPE */
  68. #endif /* !STLSOFT_CF_NEGATIVE_MODULUS_POSITIVE_GIVES_NEGATIVE_RESULT */
  69. #ifdef STLSOFT_UNITTEST
  70. # ifndef STLSOFT_INCL_STLSOFT_UTIL_H_LIMIT_TRAITS
  71. # include <stlsoft/util/limit_traits.h>
  72. # endif /* !STLSOFT_INCL_STLSOFT_UTIL_H_LIMIT_TRAITS */
  73. # include <stdio.h>
  74. # include <string.h>
  75. #endif /* STLSOFT_UNITTEST */
  76. /* /////////////////////////////////////////////////////////////////////////
  77. * Namespace
  78. */
  79. #ifndef _STLSOFT_NO_NAMESPACE
  80. namespace stlsoft
  81. {
  82. #endif /* _STLSOFT_NO_NAMESPACE */
  83. /* /////////////////////////////////////////////////////////////////////////
  84. * Macros
  85. */
  86. #ifdef __STLSOFT_INTEGER_TO_STRING_OPTIMISE_64BIT
  87. # error __STLSOFT_INTEGER_TO_STRING_OPTIMISE_64BIT is no longer supported. Instead, define STLSOFT_INTEGER_TO_STRING_OPTIMISE_64BIT
  88. #endif /* __STLSOFT_INTEGER_TO_STRING_OPTIMISE_64BIT */
  89. /* /////////////////////////////////////////////////////////////////////////
  90. * Constants
  91. */
  92. #if 0
  93. namespace constants
  94. {
  95. enum
  96. {
  97. buffer_width = 21 //!< Sufficient for sprintf()-ing 8/16/32/64 bit signed/unsigned integers
  98. };
  99. } // namespace int2str
  100. #endif /* 0 */
  101. /* /////////////////////////////////////////////////////////////////////////
  102. * Helper Functions
  103. */
  104. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  105. /** \brief Provides an indexable sequence of digit characters
  106. *
  107. * \ingroup group__library__conversion
  108. */
  109. template <ss_typename_param_k C>
  110. inline
  111. C const*
  112. #ifdef STLSOFT_CF_TEMPLATE_TYPE_REQUIRED_IN_ARGS
  113. get_digit_character(C*)
  114. #else /* ? STLSOFT_CF_TEMPLATE_TYPE_REQUIRED_IN_ARGS */
  115. get_digit_character()
  116. #endif /* STLSOFT_CF_TEMPLATE_TYPE_REQUIRED_IN_ARGS */
  117. {
  118. static C const s_characters[19] =
  119. {
  120. '9'
  121. , '8'
  122. , '7'
  123. , '6'
  124. , '5'
  125. , '4'
  126. , '3'
  127. , '2'
  128. , '1'
  129. , '0'
  130. , '1'
  131. , '2'
  132. , '3'
  133. , '4'
  134. , '5'
  135. , '6'
  136. , '7'
  137. , '8'
  138. , '9'
  139. };
  140. #if 0
  141. static C const *s_mid = s_characters + 9;
  142. return s_mid;
  143. #else /* ? 0 */
  144. return s_characters + 9;
  145. #endif /* 0 */
  146. }
  147. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  148. /* /////////////////////////////////////////////////////////////////////////
  149. * Functions
  150. */
  151. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  152. /** \brief Highly efficient conversion of unsigned integers to string
  153. *
  154. * \ingroup group__library__conversion
  155. *
  156. * \note The function does not check that cchBuf is sufficient for conversion
  157. * of the particular integer type, except for a debug version
  158. * <code>assert()</code>. It is the programmer's responsibility to ensure that
  159. * the supplied buffer is large enough for the conversion. This can be done
  160. * with the use of the printf_traits templates.
  161. *
  162. * \param buf A buffer of sufficient space within which to convert the integer
  163. * \param cchBuf The number of characters available in \c buf
  164. * \param i The integer to convert
  165. */
  166. template< ss_typename_param_k C
  167. , ss_typename_param_k I
  168. >
  169. inline
  170. C const*
  171. unsigned_integer_to_string(C* buf, ss_size_t cchBuf, I i)
  172. {
  173. C* psz = buf + cchBuf - 1; // Set pointer to last character.
  174. *psz = 0; // Set the terminating null character.
  175. do
  176. {
  177. #if defined(STLSOFT_COMPILER_IS_MSVC)
  178. typedef I rem_t;
  179. #else /* ? compiler */
  180. typedef ss_uint_t rem_t;
  181. #endif /* compiler */
  182. rem_t lsd = static_cast<rem_t>(i % 10); // Determine the least significant digit.
  183. i = static_cast<I>(i / 10); // Deal with next most significant.
  184. --psz; // Move back.
  185. #ifdef STLSOFT_CF_TEMPLATE_TYPE_REQUIRED_IN_ARGS
  186. *psz = get_digit_character(static_cast<C*>(NULL))[lsd];
  187. #else /* ? STLSOFT_CF_TEMPLATE_TYPE_REQUIRED_IN_ARGS */
  188. *psz = get_digit_character<C>()[lsd];
  189. #endif /* STLSOFT_CF_TEMPLATE_TYPE_REQUIRED_IN_ARGS */
  190. } while(i != 0);
  191. STLSOFT_ASSERT(!(psz < buf));
  192. return psz;
  193. }
  194. /** \brief Highly efficient conversion of unsigned integers to string
  195. *
  196. * \ingroup group__library__conversion
  197. *
  198. * \note The function does not check that cchBuf is sufficient for conversion
  199. * of the particular integer type, except for a debug version
  200. * <code>assert()</code>. It is the programmer's responsibility to ensure that
  201. * the supplied buffer is large enough for the conversion. This can be done
  202. * with the use of the printf_traits templates.
  203. *
  204. * \param buf A buffer of sufficient space within which to convert the integer
  205. * \param cchBuf The number of characters available in \c buf
  206. * \param i The integer to convert
  207. * \param cchRes Receives the number of characters written
  208. */
  209. template< ss_typename_param_k C
  210. , ss_typename_param_k I
  211. >
  212. inline
  213. C const*
  214. unsigned_integer_to_string(C* buf, ss_size_t cchBuf, I i, ss_size_t* cchRes)
  215. {
  216. STLSOFT_ASSERT(NULL != cchRes);
  217. C const* psz = unsigned_integer_to_string<C, I>(buf, cchBuf, i);
  218. *cchRes = cchBuf - (psz - (buf - 1));
  219. return psz;
  220. }
  221. /** \brief Highly efficient conversion of signed integers to string
  222. *
  223. * \ingroup group__library__conversion
  224. *
  225. * \note The function does not check that cchBuf is sufficient for conversion
  226. * of the particular integer type, except for a debug version
  227. * <code>assert()</code>. It is the programmer's responsibility to ensure that
  228. * the supplied buffer is large enough for the conversion. This can be done
  229. * with the use of the printf_traits templates.
  230. *
  231. * \param buf A buffer of sufficient space within which to convert the integer
  232. * \param cchBuf The number of characters available in \c buf
  233. * \param i The integer to convert
  234. */
  235. template< ss_typename_param_k C
  236. , ss_typename_param_k I
  237. >
  238. inline
  239. C const*
  240. signed_integer_to_string(C* buf, ss_size_t cchBuf, I i)
  241. {
  242. #ifndef STLSOFT_CF_NEGATIVE_MODULUS_POSITIVE_GIVES_NEGATIVE_RESULT
  243. // If the compiler does not evaluate -9 % 10 to equal -9, then we need to work
  244. // with it as if an unsigned, and prepend the -ve
  245. typedef limit_traits<I> limit_traits_t;
  246. typedef sign_traits<I> sign_traits_t;
  247. typedef ss_typename_type_k sign_traits_t::signed_type signed_type_t;
  248. typedef ss_typename_type_k sign_traits_t::unsigned_type unsigned_type_t;
  249. // If this fires, something has happened to invoke this function on an
  250. // unsigned type.
  251. STLSOFT_STATIC_ASSERT((0 != is_same_type<signed_type_t, I>::value));
  252. C const* psz;
  253. if(i == limit_traits_t::minimum())
  254. {
  255. STLSOFT_ASSERT(i == -i);
  256. // Special case of the (signed) minimum, since the maximum -ve value
  257. // of a signed integer cannot be negated.
  258. //
  259. // We instead take the equivalent value as an unsigned integer,
  260. // convert that (as unsigned), and prepend a '-'
  261. psz = unsigned_integer_to_string(buf, cchBuf, static_cast<unsigned_type_t>(limit_traits_t::minimum()));
  262. *const_cast<C*>(--psz) = C('-');
  263. }
  264. else
  265. {
  266. // Just using the unsigned version here for the absence of
  267. // sign. Perversely, The invoked function is still a signed
  268. // specialisation.
  269. psz = unsigned_integer_to_string(buf, cchBuf, i);
  270. if(i < 0)
  271. {
  272. *const_cast<C*>(--psz) = C('-');
  273. }
  274. }
  275. return psz;
  276. #else /* ? STLSOFT_CF_NEGATIVE_MODULUS_POSITIVE_GIVES_NEGATIVE_RESULT */
  277. // Compiler evaluates -9 % 10 to equal -9, so use the full -ve algorithm. This
  278. // is chosen because it is more efficient on most compilers than calling the
  279. // unsigned peer and converting.
  280. #if defined(STLSOFT_COMPILER_IS_MSVC)
  281. typedef I rem_t;
  282. #else /* ? compiler */
  283. typedef ss_sint_t rem_t;
  284. #endif /* compiler */
  285. C* psz = buf + cchBuf - 1; // Set pointer to last character.
  286. *psz = 0; // Set the terminating null character.
  287. if(i < 0)
  288. {
  289. do
  290. {
  291. rem_t lsd = static_cast<rem_t>(i % 10); // Determine the least significant digit.
  292. i = static_cast<I>(i / 10); // Deal with next most significant.
  293. --psz; // Move back.
  294. #ifdef STLSOFT_CF_TEMPLATE_TYPE_REQUIRED_IN_ARGS
  295. *psz = get_digit_character(static_cast<C*>(NULL))[lsd];
  296. #else /* ? STLSOFT_CF_TEMPLATE_TYPE_REQUIRED_IN_ARGS */
  297. *psz = get_digit_character<C>()[lsd];
  298. #endif /* STLSOFT_CF_TEMPLATE_TYPE_REQUIRED_IN_ARGS */
  299. } while(i != 0);
  300. *(--psz) = C('-'); // Prepend the minus sign.
  301. }
  302. else
  303. {
  304. do
  305. {
  306. rem_t lsd = static_cast<rem_t>(i % 10); // Determine the least significant digit.
  307. i = static_cast<I>(i / 10); // Deal with next most significant.
  308. --psz; // Move back.
  309. #ifdef STLSOFT_CF_TEMPLATE_TYPE_REQUIRED_IN_ARGS
  310. *psz = get_digit_character(static_cast<C*>(NULL))[lsd];
  311. #else /* ? STLSOFT_CF_TEMPLATE_TYPE_REQUIRED_IN_ARGS */
  312. *psz = get_digit_character<C>()[lsd];
  313. #endif /* STLSOFT_CF_TEMPLATE_TYPE_REQUIRED_IN_ARGS */
  314. } while(i != 0);
  315. }
  316. STLSOFT_ASSERT(!(psz < buf));
  317. return psz;
  318. #endif /* !STLSOFT_CF_NEGATIVE_MODULUS_POSITIVE_GIVES_NEGATIVE_RESULT */
  319. }
  320. /** \brief Highly efficient conversion of signed integers to string
  321. *
  322. * \ingroup group__library__conversion
  323. *
  324. * \note The function does not check that cchBuf is sufficient for conversion
  325. * of the particular integer type, except for a debug version
  326. * <code>assert()</code>. It is the programmer's responsibility to ensure that
  327. * the supplied buffer is large enough for the conversion. This can be done
  328. * with the use of the printf_traits templates.
  329. *
  330. * \param buf A buffer of sufficient space within which to convert the integer
  331. * \param cchBuf The number of characters available in \c buf
  332. * \param i The integer to convert
  333. * \param cchRes Receives the number of characters written
  334. */
  335. template< ss_typename_param_k C
  336. , ss_typename_param_k I
  337. >
  338. inline
  339. C const*
  340. signed_integer_to_string(C* buf, ss_size_t cchBuf, I i, ss_size_t* cchRes)
  341. {
  342. STLSOFT_ASSERT(NULL != cchRes);
  343. C const* psz = signed_integer_to_string<C, I>(buf, cchBuf, i);
  344. *cchRes = cchBuf - (psz - (buf - 1));
  345. return psz;
  346. }
  347. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  348. /** \brief Highly efficient conversion of integer to string.
  349. *
  350. * \ingroup group__library__conversion
  351. */
  352. template <ss_typename_param_k C>
  353. inline
  354. C const*
  355. integer_to_string(C* buf, ss_size_t cchBuf, ss_sint8_t i)
  356. {
  357. return signed_integer_to_string(buf, cchBuf, i);
  358. }
  359. /** \brief Highly efficient conversion of integer to string.
  360. *
  361. * \ingroup group__library__conversion
  362. */
  363. template <ss_typename_param_k C>
  364. inline
  365. C const*
  366. integer_to_string(C* buf, ss_size_t cchBuf, ss_uint8_t i)
  367. {
  368. return unsigned_integer_to_string(buf, cchBuf, i);
  369. }
  370. /** \brief Highly efficient conversion of integer to string.
  371. *
  372. * \ingroup group__library__conversion
  373. */
  374. template <ss_typename_param_k C>
  375. inline
  376. C const*
  377. integer_to_string(C* buf, ss_size_t cchBuf, ss_sint16_t i)
  378. {
  379. return signed_integer_to_string(buf, cchBuf, i);
  380. }
  381. /** \brief Highly efficient conversion of integer to string.
  382. *
  383. * \ingroup group__library__conversion
  384. */
  385. template <ss_typename_param_k C>
  386. inline
  387. C const*
  388. integer_to_string(C* buf, ss_size_t cchBuf, ss_uint16_t i)
  389. {
  390. return unsigned_integer_to_string(buf, cchBuf, i);
  391. }
  392. /** \brief Highly efficient conversion of integer to string.
  393. *
  394. * \ingroup group__library__conversion
  395. */
  396. template <ss_typename_param_k C>
  397. inline
  398. C const*
  399. integer_to_string(C* buf, ss_size_t cchBuf, ss_sint32_t i)
  400. {
  401. return signed_integer_to_string(buf, cchBuf, i);
  402. }
  403. /** \brief Highly efficient conversion of integer to string.
  404. *
  405. * \ingroup group__library__conversion
  406. */
  407. template <ss_typename_param_k C>
  408. inline
  409. C const*
  410. integer_to_string(C* buf, ss_size_t cchBuf, ss_uint32_t i)
  411. {
  412. return unsigned_integer_to_string(buf, cchBuf, i);
  413. }
  414. #ifdef STLSOFT_CF_64BIT_INT_SUPPORT
  415. /** \brief Highly efficient conversion of integer to string.
  416. *
  417. * \ingroup group__library__conversion
  418. */
  419. template <ss_typename_param_k C>
  420. inline
  421. C const*
  422. integer_to_string(C* buf, ss_size_t cchBuf, ss_sint64_t const& i)
  423. {
  424. #ifdef STLSOFT_INTEGER_TO_STRING_OPTIMISE_64BIT
  425. if(i < 0x80000000)
  426. {
  427. return signed_integer_to_string(buf, cchBuf, static_cast<ss_sint32_t>(i));
  428. }
  429. #endif // STLSOFT_INTEGER_TO_STRING_OPTIMISE_64BIT
  430. return signed_integer_to_string(buf, cchBuf, i);
  431. }
  432. /** \brief Highly efficient conversion of integer to string.
  433. *
  434. * \ingroup group__library__conversion
  435. */
  436. template <ss_typename_param_k C>
  437. inline
  438. C const*
  439. integer_to_string(C* buf, ss_size_t cchBuf, ss_uint64_t const& i)
  440. {
  441. #ifdef STLSOFT_INTEGER_TO_STRING_OPTIMISE_64BIT
  442. if(i < 0x80000000)
  443. {
  444. return unsigned_integer_to_string(buf, cchBuf, static_cast<ss_uint32_t>(i));
  445. }
  446. #endif // STLSOFT_INTEGER_TO_STRING_OPTIMISE_64BIT
  447. return unsigned_integer_to_string(buf, cchBuf, i);
  448. }
  449. #endif /* STLSOFT_CF_64BIT_INT_SUPPORT */
  450. #ifdef STLSOFT_CF_INT_DISTINCT_INT_TYPE
  451. /** \brief Highly efficient conversion of integer to string.
  452. *
  453. * \ingroup group__library__conversion
  454. */
  455. template <ss_typename_param_k C>
  456. inline
  457. C const*
  458. integer_to_string(C* buf, ss_size_t cchBuf, int i)
  459. {
  460. return signed_integer_to_string(buf, cchBuf, i);
  461. }
  462. /** \brief Highly efficient conversion of integer to string.
  463. *
  464. * \ingroup group__library__conversion
  465. */
  466. template <ss_typename_param_k C>
  467. inline
  468. C const*
  469. integer_to_string(C* buf, ss_size_t cchBuf, unsigned int i)
  470. {
  471. return unsigned_integer_to_string(buf, cchBuf, i);
  472. }
  473. #endif /* !STLSOFT_CF_INT_DISTINCT_INT_TYPE */
  474. #ifdef STLSOFT_CF_LONG_DISTINCT_INT_TYPE
  475. /** \brief Highly efficient conversion of integer to string.
  476. *
  477. * \ingroup group__library__conversion
  478. */
  479. template <ss_typename_param_k C>
  480. inline
  481. C const*
  482. integer_to_string(C* buf, ss_size_t cchBuf, long i)
  483. {
  484. return signed_integer_to_string(buf, cchBuf, i);
  485. }
  486. /** \brief Highly efficient conversion of integer to string.
  487. *
  488. * \ingroup group__library__conversion
  489. */
  490. template <ss_typename_param_k C>
  491. inline
  492. C const*
  493. integer_to_string(C* buf, ss_size_t cchBuf, unsigned long i)
  494. {
  495. return unsigned_integer_to_string(buf, cchBuf, i);
  496. }
  497. #endif /* !STLSOFT_CF_LONG_DISTINCT_INT_TYPE */
  498. #ifdef STLSOFT_CF_STATIC_ARRAY_SIZE_DETERMINATION_SUPPORT
  499. /** \brief Highly efficient conversion of integer to string.
  500. *
  501. * \ingroup group__library__conversion
  502. */
  503. template< ss_typename_param_k C
  504. , ss_size_t N
  505. >
  506. inline
  507. C const*
  508. integer_to_string(C (&buf)[N], ss_sint8_t i)
  509. {
  510. STLSOFT_STATIC_ASSERT(!(N < 5));
  511. return signed_integer_to_string(buf, N, i);
  512. }
  513. /** \brief Highly efficient conversion of integer to string.
  514. *
  515. * \ingroup group__library__conversion
  516. */
  517. template< ss_typename_param_k C
  518. , ss_size_t N
  519. >
  520. inline
  521. C const*
  522. integer_to_string(C (&buf)[N], ss_uint8_t i)
  523. {
  524. STLSOFT_STATIC_ASSERT(!(N < 4));
  525. return unsigned_integer_to_string(buf, N, i);
  526. }
  527. /** \brief Highly efficient conversion of integer to string.
  528. *
  529. * \ingroup group__library__conversion
  530. */
  531. template< ss_typename_param_k C
  532. , ss_size_t N
  533. >
  534. inline
  535. C const*
  536. integer_to_string(C (&buf)[N], ss_sint16_t i)
  537. {
  538. STLSOFT_STATIC_ASSERT(!(N < 7));
  539. return signed_integer_to_string(buf, N, i);
  540. }
  541. /** \brief Highly efficient conversion of integer to string.
  542. *
  543. * \ingroup group__library__conversion
  544. */
  545. template< ss_typename_param_k C
  546. , ss_size_t N
  547. >
  548. inline
  549. C const*
  550. integer_to_string(C (&buf)[N], ss_uint16_t i)
  551. {
  552. STLSOFT_STATIC_ASSERT(!(N < 6));
  553. return unsigned_integer_to_string(buf, N, i);
  554. }
  555. /** \brief Highly efficient conversion of integer to string.
  556. *
  557. * \ingroup group__library__conversion
  558. */
  559. template< ss_typename_param_k C
  560. , ss_size_t N
  561. >
  562. inline
  563. C const*
  564. integer_to_string(C (&buf)[N], ss_sint32_t i)
  565. {
  566. STLSOFT_STATIC_ASSERT(!(N < 12));
  567. return signed_integer_to_string(buf, N, i);
  568. }
  569. /** \brief Highly efficient conversion of integer to string.
  570. *
  571. * \ingroup group__library__conversion
  572. */
  573. template< ss_typename_param_k C
  574. , ss_size_t N
  575. >
  576. inline
  577. C const*
  578. integer_to_string(C (&buf)[N], ss_uint32_t i)
  579. {
  580. STLSOFT_STATIC_ASSERT(!(N < 11));
  581. return unsigned_integer_to_string(buf, N, i);
  582. }
  583. #ifdef STLSOFT_CF_64BIT_INT_SUPPORT
  584. /** \brief Highly efficient conversion of integer to string.
  585. *
  586. * \ingroup group__library__conversion
  587. */
  588. template< ss_typename_param_k C
  589. , ss_size_t N
  590. >
  591. inline
  592. C const*
  593. integer_to_string(C (&buf)[N], ss_sint64_t const& i)
  594. {
  595. STLSOFT_STATIC_ASSERT(!(N < 21));
  596. #ifdef STLSOFT_INTEGER_TO_STRING_OPTIMISE_64BIT
  597. if(i < 0x80000000)
  598. {
  599. return signed_integer_to_string(buf, N, static_cast<ss_sint32_t>(i));
  600. }
  601. #endif // STLSOFT_INTEGER_TO_STRING_OPTIMISE_64BIT
  602. return signed_integer_to_string(buf, N, i);
  603. }
  604. /** \brief Highly efficient conversion of integer to string.
  605. *
  606. * \ingroup group__library__conversion
  607. */
  608. template< ss_typename_param_k C
  609. , ss_size_t N
  610. >
  611. inline
  612. C const*
  613. integer_to_string(C (&buf)[N], ss_uint64_t const& i)
  614. {
  615. STLSOFT_STATIC_ASSERT(!(N < 21));
  616. #ifdef STLSOFT_INTEGER_TO_STRING_OPTIMISE_64BIT
  617. if(i < 0x80000000)
  618. {
  619. return unsigned_integer_to_string(buf, N, static_cast<ss_uint32_t>(i));
  620. }
  621. #endif // STLSOFT_INTEGER_TO_STRING_OPTIMISE_64BIT
  622. return unsigned_integer_to_string(buf, N, i);
  623. }
  624. #endif /* STLSOFT_CF_64BIT_INT_SUPPORT */
  625. #ifdef STLSOFT_CF_INT_DISTINCT_INT_TYPE
  626. /** \brief Highly efficient conversion of integer to string.
  627. *
  628. * \ingroup group__library__conversion
  629. */
  630. template< ss_typename_param_k C
  631. , ss_size_t N
  632. >
  633. inline
  634. C const*
  635. integer_to_string(C (&buf)[N], int i)
  636. {
  637. return signed_integer_to_string(buf, N, i);
  638. }
  639. /** \brief Highly efficient conversion of integer to string.
  640. *
  641. * \ingroup group__library__conversion
  642. */
  643. template< ss_typename_param_k C
  644. , ss_size_t N
  645. >
  646. inline
  647. C const*
  648. integer_to_string(C (&buf)[N], unsigned int i)
  649. {
  650. return signed_integer_to_string(buf, N, i);
  651. }
  652. #endif /* !STLSOFT_CF_INT_DISTINCT_INT_TYPE */
  653. #ifdef STLSOFT_CF_LONG_DISTINCT_INT_TYPE
  654. /** \brief Highly efficient conversion of integer to string.
  655. *
  656. * \ingroup group__library__conversion
  657. */
  658. template< ss_typename_param_k C
  659. , ss_size_t N
  660. >
  661. inline
  662. C const*
  663. integer_to_string(C (&buf)[N], long i)
  664. {
  665. return signed_integer_to_string(buf, N, i);
  666. }
  667. /** \brief Highly efficient conversion of integer to string.
  668. *
  669. * \ingroup group__library__conversion
  670. */
  671. template< ss_typename_param_k C
  672. , ss_size_t N
  673. >
  674. inline
  675. C const*
  676. integer_to_string(C (&buf)[N], unsigned long i)
  677. {
  678. return signed_integer_to_string(buf, N, i);
  679. }
  680. #endif /* !STLSOFT_CF_LONG_DISTINCT_INT_TYPE */
  681. #endif /* STLSOFT_CF_STATIC_ARRAY_SIZE_DETERMINATION_SUPPORT */
  682. #if 0
  683. template <ss_typename_param_k C>
  684. inline
  685. C const*
  686. integer_to_string(C* buf, ss_size_t cchBuf, ss_int_t i)
  687. {
  688. return signed_integer_to_string(buf, cchBuf, i);
  689. }
  690. template <ss_typename_param_k C>
  691. inline
  692. C const*
  693. integer_to_string(C* buf, ss_size_t cchBuf, ss_uint_t i)
  694. {
  695. return unsigned_integer_to_string(buf, cchBuf, i);
  696. }
  697. template <ss_typename_param_k C>
  698. inline
  699. C const*
  700. integer_to_string(C* buf, ss_size_t cchBuf, ss_bool_t i);
  701. template <ss_typename_param_k C>
  702. inline
  703. C const*
  704. integer_to_string(C* buf, ss_size_t cchBuf, ss_char_a_t i);
  705. template <ss_typename_param_k C>
  706. inline
  707. C const*
  708. integer_to_string(C* buf, ss_size_t cchBuf, ss_char_w_t i);
  709. #endif /* 0 */
  710. /** \brief Highly efficient conversion of integer to string.
  711. *
  712. * \ingroup group__library__conversion
  713. */
  714. template <ss_typename_param_k C>
  715. inline
  716. C const*
  717. integer_to_string(C* buf, ss_size_t cchBuf, ss_sint8_t i, ss_size_t* pcchRes)
  718. {
  719. STLSOFT_ASSERT(NULL != pcchRes);
  720. return signed_integer_to_string(buf, cchBuf, i, pcchRes);
  721. }
  722. template <ss_typename_param_k C>
  723. STLSOFT_DECLARE_DEPRECATION_MESSAGE("The overloads of integer_to_string() that use a reference out-parameter to receive the written length are deprecated and will be removed in a future version of STLSoft; use the new pointer out-parameter overloads instead")
  724. inline
  725. C const*
  726. integer_to_string(C* buf, ss_size_t cchBuf, ss_sint8_t i, ss_size_t& cchRes)
  727. {
  728. return signed_integer_to_string(buf, cchBuf, i, &cchRes);
  729. }
  730. /** \brief Highly efficient conversion of integer to string.
  731. *
  732. * \ingroup group__library__conversion
  733. */
  734. template <ss_typename_param_k C>
  735. inline
  736. C const*
  737. integer_to_string(C* buf, ss_size_t cchBuf, ss_uint8_t i, ss_size_t* pcchRes)
  738. {
  739. STLSOFT_ASSERT(NULL != pcchRes);
  740. return unsigned_integer_to_string(buf, cchBuf, i, pcchRes);
  741. }
  742. template <ss_typename_param_k C>
  743. STLSOFT_DECLARE_DEPRECATION_MESSAGE("The overloads of integer_to_string() that use a reference out-parameter to receive the written length are deprecated and will be removed in a future version of STLSoft; use the new pointer out-parameter overloads instead")
  744. inline
  745. C const*
  746. integer_to_string(C* buf, ss_size_t cchBuf, ss_uint8_t i, ss_size_t& cchRes)
  747. {
  748. return unsigned_integer_to_string(buf, cchBuf, i, &cchRes);
  749. }
  750. /** \brief Highly efficient conversion of integer to string.
  751. *
  752. * \ingroup group__library__conversion
  753. */
  754. template <ss_typename_param_k C>
  755. inline
  756. C const*
  757. integer_to_string(C* buf, ss_size_t cchBuf, ss_sint16_t i, ss_size_t* pcchRes)
  758. {
  759. STLSOFT_ASSERT(NULL != pcchRes);
  760. return signed_integer_to_string(buf, cchBuf, i, pcchRes);
  761. }
  762. template <ss_typename_param_k C>
  763. STLSOFT_DECLARE_DEPRECATION_MESSAGE("The overloads of integer_to_string() that use a reference out-parameter to receive the written length are deprecated and will be removed in a future version of STLSoft; use the new pointer out-parameter overloads instead")
  764. inline
  765. C const*
  766. integer_to_string(C* buf, ss_size_t cchBuf, ss_sint16_t i, ss_size_t& cchRes)
  767. {
  768. return signed_integer_to_string(buf, cchBuf, i, &cchRes);
  769. }
  770. /** \brief Highly efficient conversion of integer to string.
  771. *
  772. * \ingroup group__library__conversion
  773. */
  774. template <ss_typename_param_k C>
  775. inline
  776. C const*
  777. integer_to_string(C* buf, ss_size_t cchBuf, ss_uint16_t i, ss_size_t* pcchRes)
  778. {
  779. STLSOFT_ASSERT(NULL != pcchRes);
  780. return unsigned_integer_to_string(buf, cchBuf, i, pcchRes);
  781. }
  782. template <ss_typename_param_k C>
  783. STLSOFT_DECLARE_DEPRECATION_MESSAGE("The overloads of integer_to_string() that use a reference out-parameter to receive the written length are deprecated and will be removed in a future version of STLSoft; use the new pointer out-parameter overloads instead")
  784. inline
  785. C const*
  786. integer_to_string(C* buf, ss_size_t cchBuf, ss_uint16_t i, ss_size_t& cchRes)
  787. {
  788. return unsigned_integer_to_string(buf, cchBuf, i, &cchRes);
  789. }
  790. /** \brief Highly efficient conversion of integer to string.
  791. *
  792. * \ingroup group__library__conversion
  793. */
  794. template <ss_typename_param_k C>
  795. inline
  796. C const*
  797. integer_to_string(C* buf, ss_size_t cchBuf, ss_sint32_t i, ss_size_t* pcchRes)
  798. {
  799. STLSOFT_ASSERT(NULL != pcchRes);
  800. return signed_integer_to_string(buf, cchBuf, i, pcchRes);
  801. }
  802. template <ss_typename_param_k C>
  803. STLSOFT_DECLARE_DEPRECATION_MESSAGE("The overloads of integer_to_string() that use a reference out-parameter to receive the written length are deprecated and will be removed in a future version of STLSoft; use the new pointer out-parameter overloads instead")
  804. inline
  805. C const*
  806. integer_to_string(C* buf, ss_size_t cchBuf, ss_sint32_t i, ss_size_t& cchRes)
  807. {
  808. return signed_integer_to_string(buf, cchBuf, i, &cchRes);
  809. }
  810. /** \brief Highly efficient conversion of integer to string.
  811. *
  812. * \ingroup group__library__conversion
  813. */
  814. template <ss_typename_param_k C>
  815. inline
  816. C const*
  817. integer_to_string(C* buf, ss_size_t cchBuf, ss_uint32_t i, ss_size_t* pcchRes)
  818. {
  819. STLSOFT_ASSERT(NULL != pcchRes);
  820. return unsigned_integer_to_string(buf, cchBuf, i, pcchRes);
  821. }
  822. template <ss_typename_param_k C>
  823. STLSOFT_DECLARE_DEPRECATION_MESSAGE("The overloads of integer_to_string() that use a reference out-parameter to receive the written length are deprecated and will be removed in a future version of STLSoft; use the new pointer out-parameter overloads instead")
  824. inline
  825. C const*
  826. integer_to_string(C* buf, ss_size_t cchBuf, ss_uint32_t i, ss_size_t& cchRes)
  827. {
  828. return unsigned_integer_to_string(buf, cchBuf, i, &cchRes);
  829. }
  830. #ifdef STLSOFT_CF_64BIT_INT_SUPPORT
  831. /** \brief Highly efficient conversion of integer to string.
  832. *
  833. * \ingroup group__library__conversion
  834. */
  835. template <ss_typename_param_k C>
  836. inline
  837. C const*
  838. integer_to_string(C* buf, ss_size_t cchBuf, ss_sint64_t const& i, ss_size_t* pcchRes)
  839. {
  840. STLSOFT_ASSERT(NULL != pcchRes);
  841. return signed_integer_to_string(buf, cchBuf, i, pcchRes);
  842. }
  843. template <ss_typename_param_k C>
  844. STLSOFT_DECLARE_DEPRECATION_MESSAGE("The overloads of integer_to_string() that use a reference out-parameter to receive the written length are deprecated and will be removed in a future version of STLSoft; use the new pointer out-parameter overloads instead")
  845. inline
  846. C const*
  847. integer_to_string(C* buf, ss_size_t cchBuf, ss_sint64_t const& i, ss_size_t& cchRes)
  848. {
  849. return signed_integer_to_string(buf, cchBuf, i, &cchRes);
  850. }
  851. /** \brief Highly efficient conversion of integer to string.
  852. *
  853. * \ingroup group__library__conversion
  854. */
  855. template <ss_typename_param_k C>
  856. inline
  857. C const*
  858. integer_to_string(C* buf, ss_size_t cchBuf, ss_uint64_t const& i, ss_size_t* pcchRes)
  859. {
  860. STLSOFT_ASSERT(NULL != pcchRes);
  861. return unsigned_integer_to_string(buf, cchBuf, i, pcchRes);
  862. }
  863. template <ss_typename_param_k C>
  864. STLSOFT_DECLARE_DEPRECATION_MESSAGE("The overloads of integer_to_string() that use a reference out-parameter to receive the written length are deprecated and will be removed in a future version of STLSoft; use the new pointer out-parameter overloads instead")
  865. inline
  866. C const*
  867. integer_to_string(C* buf, ss_size_t cchBuf, ss_uint64_t const& i, ss_size_t& cchRes)
  868. {
  869. return unsigned_integer_to_string(buf, cchBuf, i, &cchRes);
  870. }
  871. #endif /* STLSOFT_CF_64BIT_INT_SUPPORT */
  872. #ifdef STLSOFT_CF_INT_DISTINCT_INT_TYPE
  873. /** \brief Highly efficient conversion of integer to string.
  874. *
  875. * \ingroup group__library__conversion
  876. */
  877. template <ss_typename_param_k C>
  878. inline
  879. C const*
  880. integer_to_string(C* buf, ss_size_t cchBuf, int i, ss_size_t* pcchRes)
  881. {
  882. STLSOFT_ASSERT(NULL != pcchRes);
  883. return signed_integer_to_string(buf, cchBuf, i, pcchRes);
  884. }
  885. template <ss_typename_param_k C>
  886. STLSOFT_DECLARE_DEPRECATION_MESSAGE("The overloads of integer_to_string() that use a reference out-parameter to receive the written length are deprecated and will be removed in a future version of STLSoft; use the new pointer out-parameter overloads instead")
  887. inline
  888. C const*
  889. integer_to_string(C* buf, ss_size_t cchBuf, int i, ss_size_t& cchRes)
  890. {
  891. return signed_integer_to_string(buf, cchBuf, i, &cchRes);
  892. }
  893. /** \brief Highly efficient conversion of integer to string.
  894. *
  895. * \ingroup group__library__conversion
  896. */
  897. template <ss_typename_param_k C>
  898. inline
  899. C const*
  900. integer_to_string(C* buf, ss_size_t cchBuf, unsigned int i, ss_size_t* pcchRes)
  901. {
  902. STLSOFT_ASSERT(NULL != pcchRes);
  903. return unsigned_integer_to_string(buf, cchBuf, i, pcchRes);
  904. }
  905. template <ss_typename_param_k C>
  906. STLSOFT_DECLARE_DEPRECATION_MESSAGE("The overloads of integer_to_string() that use a reference out-parameter to receive the written length are deprecated and will be removed in a future version of STLSoft; use the new pointer out-parameter overloads instead")
  907. inline
  908. C const*
  909. integer_to_string(C* buf, ss_size_t cchBuf, unsigned int i, ss_size_t& cchRes)
  910. {
  911. return unsigned_integer_to_string(buf, cchBuf, i, &cchRes);
  912. }
  913. #endif /* !STLSOFT_CF_INT_DISTINCT_INT_TYPE */
  914. #ifdef STLSOFT_CF_LONG_DISTINCT_INT_TYPE
  915. /** \brief Highly efficient conversion of integer to string.
  916. *
  917. * \ingroup group__library__conversion
  918. */
  919. template <ss_typename_param_k C>
  920. inline
  921. C const*
  922. integer_to_string(C* buf, ss_size_t cchBuf, long i, ss_size_t* pcchRes)
  923. {
  924. STLSOFT_ASSERT(NULL != pcchRes);
  925. return signed_integer_to_string(buf, cchBuf, i, pcchRes);
  926. }
  927. template <ss_typename_param_k C>
  928. STLSOFT_DECLARE_DEPRECATION_MESSAGE("The overloads of integer_to_string() that use a reference out-parameter to receive the written length are deprecated and will be removed in a future version of STLSoft; use the new pointer out-parameter overloads instead")
  929. inline
  930. C const*
  931. integer_to_string(C* buf, ss_size_t cchBuf, long i, ss_size_t& cchRes)
  932. {
  933. return signed_integer_to_string(buf, cchBuf, i, &cchRes);
  934. }
  935. /** \brief Highly efficient conversion of integer to string.
  936. *
  937. * \ingroup group__library__conversion
  938. */
  939. template <ss_typename_param_k C>
  940. inline
  941. C const*
  942. integer_to_string(C* buf, ss_size_t cchBuf, unsigned long i, ss_size_t* pcchRes)
  943. {
  944. STLSOFT_ASSERT(NULL != pcchRes);
  945. return unsigned_integer_to_string(buf, cchBuf, i, pcchRes);
  946. }
  947. template <ss_typename_param_k C>
  948. STLSOFT_DECLARE_DEPRECATION_MESSAGE("The overloads of integer_to_string() that use a reference out-parameter to receive the written length are deprecated and will be removed in a future version of STLSoft; use the new pointer out-parameter overloads instead")
  949. inline
  950. C const*
  951. integer_to_string(C* buf, ss_size_t cchBuf, unsigned long i, ss_size_t& cchRes)
  952. {
  953. return unsigned_integer_to_string(buf, cchBuf, i, &cchRes);
  954. }
  955. #endif /* !STLSOFT_CF_LONG_DISTINCT_INT_TYPE */
  956. ////////////////////////////////////////////////////////////////////////////
  957. // Unit-testing
  958. #ifdef STLSOFT_UNITTEST
  959. # include "./unittest/integer_to_string_unittest_.h"
  960. #endif /* STLSOFT_UNITTEST */
  961. /* ////////////////////////////////////////////////////////////////////// */
  962. #ifndef _STLSOFT_NO_NAMESPACE
  963. } // namespace stlsoft
  964. #endif /* _STLSOFT_NO_NAMESPACE */
  965. /* ////////////////////////////////////////////////////////////////////// */
  966. #endif /* !STLSOFT_INCL_STLSOFT_CONVERSION_HPP_INTEGER_TO_STRING */
  967. /* ///////////////////////////// end of file //////////////////////////// */