format_test2.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. // ------------------------------------------------------------------------------
  2. // format_test2.cpp : a few real, simple tests.
  3. // ------------------------------------------------------------------------------
  4. // Copyright Samuel Krempp 2003. Use, modification, and distribution are
  5. // subject to the Boost Software License, Version 1.0. (See accompanying
  6. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. // see http://www.boost.org/libs/format for library home page
  8. // ------------------------------------------------------------------------------
  9. #include <boost/algorithm/string.hpp>
  10. #include <boost/config.hpp>
  11. #include <boost/detail/lightweight_test.hpp>
  12. #include <boost/format.hpp>
  13. #include <boost/predef.h>
  14. #include <iostream>
  15. #include <iomanip>
  16. #if !defined(BOOST_NO_STD_LOCALE)
  17. #include <locale>
  18. #endif
  19. struct Rational {
  20. int n,d;
  21. Rational (int an, int ad) : n(an), d(ad) {}
  22. };
  23. std::ostream& operator<<( std::ostream& os, const Rational& r) {
  24. os << r.n << "/" << r.d;
  25. return os;
  26. }
  27. #if !defined(BOOST_NO_STD_LOCALE)
  28. // in C++03 this has to be globally defined or gcc complains
  29. struct custom_tf : std::numpunct<char> {
  30. std::string do_truename() const { return "POSITIVE"; }
  31. std::string do_falsename() const { return "NEGATIVE"; }
  32. };
  33. #endif
  34. int main(int, char* [])
  35. {
  36. using namespace std;
  37. using boost::format;
  38. using boost::io::group;
  39. using boost::str;
  40. Rational r(16,9);
  41. const Rational cr(9,16);
  42. string s;
  43. s = str(format("%5%. %5$=6s . %1% format %5%, c'%3% %1% %2%.\n")
  44. % "le" % "bonheur" % "est" % "trop" % group(setfill('_'), "bref") );
  45. if(s != "bref. _bref_ . le format bref, c'est le bonheur.\n") {
  46. cerr << s;
  47. BOOST_ERROR("centered alignement : formatting result incorrect");
  48. }
  49. s = str(format("%+8d %-8d\n") % r % cr );
  50. if(s != " +16/+9 9/16 \n") {
  51. cerr << s;
  52. BOOST_ERROR("(user-type) formatting result incorrect");
  53. }
  54. s = str(format("[%0+4d %0+8d %-08d]\n") % 8 % r % r);
  55. if(s != "[+008 +0016/+9 16/9 ]\n") {
  56. cerr << s;
  57. BOOST_ERROR("(zero-padded user-type) formatting result incorrect");
  58. }
  59. s = str( format("%1%, %20T_ (%|2$5|,%|3$5|)\n") % "98765" % 1326 % 88 ) ;
  60. if( s != "98765, _____________ ( 1326, 88)\n" )
  61. BOOST_ERROR("(tabulation) formatting result incorrect");
  62. s = str( format("%s, %|20t|=") % 88 ) ;
  63. if( s != "88, =" ) {
  64. cout << s << endl;
  65. BOOST_ERROR("(tabulation) formatting result incorrect");
  66. }
  67. s = str(format("%.2s %8c.\n") % "root" % "user" );
  68. if(s != "ro u.\n") {
  69. cerr << s;
  70. BOOST_ERROR("(truncation) formatting result incorrect");
  71. }
  72. // width in format-string is overridden by setw manipulator :
  73. s = str( format("%|1$4| %|1$|") % group(setfill('0'), setw(6), 1) );
  74. if( s!= "000001 000001")
  75. BOOST_ERROR("width in format VS in argument misbehaved");
  76. s = str( format("%|=s|") % group(setfill('_'), setw(6), r) );
  77. if( s!= "_16/9_") {
  78. cerr << s << endl;
  79. BOOST_ERROR("width in group context is not handled correctly");
  80. }
  81. // options that uses internal alignment : + 0 #
  82. s = str( format("%+6d %0#6x %s\n") % 342 % 33 % "ok" );
  83. if( s !=" +342 0x0021 ok\n")
  84. BOOST_ERROR("(flags +, 0, or #) formatting result incorrect");
  85. // flags in the format string are not sticky
  86. // and hex in argument overrrides type-char d (->decimal) :
  87. s = str( format("%2$#4d %|1$4| %|2$#4| %|3$|")
  88. % 101
  89. % group(setfill('_'), hex, 2)
  90. % 103 );
  91. if(s != "_0x2 101 _0x2 103")
  92. BOOST_ERROR("formatting error. (not-restoring state ?)");
  93. // flag '0' is tricky .
  94. // left-align cancels '0':
  95. s = str( format("%2$0#12X %2$0#-12d %1$0#10d \n") % -20 % 10 );
  96. if( s != "0X000000000A 10 -000000020 \n"){
  97. cerr << s;
  98. BOOST_ERROR("formatting error. (flag 0)");
  99. }
  100. // actually testing floating point output is implementation
  101. // specific so we're just going to do minimal checking...
  102. double dbl = 1234567.890123f;
  103. #if (__cplusplus >= 201103L) || (BOOST_VERSION_NUMBER_MAJOR(BOOST_COMP_MSVC) >= 12)
  104. // msvc-12.0 and later have support for hexfloat but do not set __cplusplus to a C++11 value
  105. BOOST_TEST(boost::starts_with((boost::format("%A") % dbl).str(), "0X"));
  106. BOOST_TEST(boost::starts_with((boost::format("%a") % dbl).str(), "0x"));
  107. #endif
  108. BOOST_TEST(boost::contains((boost::format("%E") % dbl).str(), "E"));
  109. BOOST_TEST(boost::contains((boost::format("%e") % dbl).str(), "e"));
  110. BOOST_TEST(boost::contains((boost::format("%F") % dbl).str(), "."));
  111. BOOST_TEST(boost::contains((boost::format("%f") % dbl).str(), "."));
  112. BOOST_TEST(!(boost::format("%G") % dbl).str().empty());
  113. BOOST_TEST(!(boost::format("%g") % dbl).str().empty());
  114. // testing argument type parsing - remember argument types are ignored
  115. // because operator % presents the argument type.
  116. unsigned int value = 456;
  117. BOOST_TEST_EQ((boost::format("%hhu") % value).str(), "456");
  118. BOOST_TEST_EQ((boost::format("%hu") % value).str(), "456");
  119. BOOST_TEST_EQ((boost::format("%lu") % value).str(), "456");
  120. BOOST_TEST_EQ((boost::format("%llu") % value).str(), "456");
  121. BOOST_TEST_EQ((boost::format("%ju") % value).str(), "456");
  122. BOOST_TEST_EQ((boost::format("%zu") % value).str(), "456");
  123. BOOST_TEST(boost::starts_with((boost::format("%Lf") % value).str(), "456"));
  124. #if !defined(BOOST_NO_STD_LOCALE)
  125. // boolalpha support
  126. std::locale loc;
  127. const std::numpunct<char>& punk(std::use_facet<std::numpunct<char> >(loc));
  128. // Demonstrates how to modify the default string to something else
  129. std::locale custom(std::locale(), new custom_tf);
  130. boost::ignore_unused(locale::global(custom));
  131. BOOST_TEST_EQ((boost::format("%b") % false).str(), "NEGATIVE");
  132. BOOST_TEST_EQ((boost::format("%b") % true).str(), "POSITIVE");
  133. // restore system default
  134. locale::global(loc);
  135. BOOST_TEST_EQ((boost::format("%b") % false).str(), punk.falsename());
  136. BOOST_TEST_EQ((boost::format("%b") % true).str(), punk.truename());
  137. #endif
  138. // Support for microsoft argument type specifiers: 'w' (same as 'l'), I, I32, I64
  139. BOOST_TEST_EQ((boost::format("%wc") % '5').str(), "5");
  140. BOOST_TEST_EQ((boost::format("%Id") % 123).str(), "123");
  141. BOOST_TEST_EQ((boost::format("%I32d") % 456).str(), "456");
  142. BOOST_TEST_EQ((boost::format("%I64d") % 789).str(), "789");
  143. // issue-36 volatile (and const) keyword
  144. volatile int vint = 1234567;
  145. BOOST_TEST_EQ((boost::format("%1%") % vint).str(), "1234567");
  146. volatile const int vcint = 7654321;
  147. BOOST_TEST_EQ((boost::format("%1%") % vcint).str(), "7654321");
  148. // skip width if '*'
  149. BOOST_TEST_EQ((boost::format("%*d") % vint).str(), "1234567");
  150. // internal ios flag
  151. BOOST_TEST_EQ((boost::format("%_6d") % -77).str(), "- 77");
  152. // combining some flags
  153. BOOST_TEST_EQ((boost::format("%+05.5d" ) % 77).str(), "+0077");
  154. BOOST_TEST_EQ((boost::format("%+ 5.5d" ) % 77).str(), " +77");
  155. BOOST_TEST_EQ((boost::format("%+_ 5.5d" ) % 77).str(), "+ 77");
  156. BOOST_TEST_EQ((boost::format("%+- 5.5d" ) % 77).str(), "+77 ");
  157. BOOST_TEST_EQ((boost::format("%+05.5d" ) % -77).str(), "-0077");
  158. BOOST_TEST_EQ((boost::format("%+ 5.5d" ) % -77).str(), " -77");
  159. BOOST_TEST_EQ((boost::format("%+_ 5.5d" ) % -77).str(), "- 77");
  160. BOOST_TEST_EQ((boost::format("%+- 5.5d" ) % -77).str(), "-77 ");
  161. // reuse state and reset format flags
  162. std::string mystr("abcdefghijklmnop");
  163. BOOST_TEST_EQ((boost::format("%2.2s %-4.4s % 8.8s")
  164. % mystr % mystr % mystr).str(), "ab abcd abcdefg");
  165. // coverage, operator =
  166. format fmt("%1%%2%%3%");
  167. fmt = fmt;
  168. return boost::report_errors();
  169. }