1// 1999-11-15 Kevin Ediger  <kediger@licor.com>
2// test the floating point inserters (facet num_put)
3
4// Copyright (C) 1999-2015 Free Software Foundation, Inc.
5//
6// This file is part of the GNU ISO C++ Library.  This library is free
7// software; you can redistribute it and/or modify it under the
8// terms of the GNU General Public License as published by the
9// Free Software Foundation; either version 3, or (at your option)
10// any later version.
11
12// This library is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16
17// You should have received a copy of the GNU General Public License along
18// with this library; see the file COPYING3.  If not see
19// <http://www.gnu.org/licenses/>.
20
21#include <iostream>
22#include <iomanip>
23#include <sstream>
24#include <limits>
25#include <testsuite_hooks.h>
26
27using namespace std;
28
29#ifndef _GLIBCXX_ASSERT
30#  define TEST_NUMPUT_VERBOSE 1
31#endif
32
33struct _TestCase
34{
35  double val;
36
37  int precision;
38  int width;
39  char decimal;
40  char fill;
41
42  bool fixed;
43  bool scientific;
44  bool showpos;
45  bool showpoint;
46  bool uppercase;
47  bool internal;
48  bool left;
49  bool right;
50
51  const char* result;
52};
53
54static bool T=true;
55static bool F=false;
56
57static _TestCase testcases[] =
58{
59  // standard output (no formatting applied)
60  { 1.2, 6,0,'.',' ', F,F,F,F,F,F,F,F, "1.2" },
61  { 54, 6,0,'.',' ', F,F,F,F,F,F,F,F, "54" },
62  { -.012, 6,0,'.',' ', F,F,F,F,F,F,F,F, "-0.012" },
63  { -.00000012, 6,0,'.',' ', F,F,F,F,F,F,F,F, "-1.2e-07" },
64
65  // fixed formatting
66  { 10.2345, 0,0,'.',' ', T,F,F,F,F,F,F,F, "10" },
67  { 10.2345, 0,0,'.',' ', T,F,F,T,F,F,F,F, "10." },
68  { 10.2345, 1,0,'.',' ', T,F,F,F,F,F,F,F, "10.2" },
69  { 10.2345, 4,0,'.',' ', T,F,F,F,F,F,F,F, "10.2345" },
70  { 10.2345, 6,0,'.',' ', T,F,T,F,F,F,F,F, "+10.234500" },
71  { -10.2345, 6,0,'.',' ', T,F,F,F,F,F,F,F, "-10.234500" },
72  { -10.2345, 6,0,',',' ', T,F,F,F,F,F,F,F, "-10,234500" },
73
74  // fixed formatting with width
75  { 10.2345, 4,5,'.',' ', T,F,F,F,F,F,F,F, "10.2345" },
76  { 10.2345, 4,6,'.',' ', T,F,F,F,F,F,F,F, "10.2345" },
77  { 10.2345, 4,7,'.',' ', T,F,F,F,F,F,F,F, "10.2345" },
78  { 10.2345, 4,8,'.',' ', T,F,F,F,F,F,F,F, " 10.2345" },
79  { 10.2345, 4,10,'.',' ', T,F,F,F,F,F,F,F, "   10.2345" },
80  { 10.2345, 4,10,'.',' ', T,F,F,F,F,F,T,F, "10.2345   " },
81  { 10.2345, 4,10,'.',' ', T,F,F,F,F,F,F,T, "   10.2345" },
82  { 10.2345, 4,10,'.',' ', T,F,F,F,F,T,F,F, "   10.2345" },
83  { -10.2345, 4,10,'.',' ', T,F,F,F,F,T,F,F, "-  10.2345" },
84  { -10.2345, 4,10,'.','A', T,F,F,F,F,T,F,F, "-AA10.2345" },
85  { 10.2345, 4,10,'.','#', T,F,T,F,F,T,F,F, "+##10.2345" },
86
87  // scientific formatting
88  { 1.23e+12, 1,0,'.',' ', F,T,F,F,F,F,F,F, "1.2e+12" },
89  { 1.23e+12, 1,0,'.',' ', F,T,F,F,T,F,F,F, "1.2E+12" },
90  { 1.23e+12, 2,0,'.',' ', F,T,F,F,F,F,F,F, "1.23e+12" },
91  { 1.23e+12, 3,0,'.',' ', F,T,F,F,F,F,F,F, "1.230e+12" },
92  { 1.23e+12, 3,0,'.',' ', F,T,T,F,F,F,F,F, "+1.230e+12" },
93  { -1.23e-12, 3,0,'.',' ', F,T,F,F,F,F,F,F, "-1.230e-12" },
94  { 1.23e+12, 3,0,',',' ', F,T,F,F,F,F,F,F, "1,230e+12" },
95};
96
97template<typename _CharT>
98class testpunct : public numpunct<_CharT>
99{
100public:
101  typedef _CharT  char_type;
102  const char_type dchar;
103
104  explicit
105  testpunct(char_type decimal_char) : numpunct<_CharT>(), dchar(decimal_char)
106  { }
107
108protected:
109  char_type
110  do_decimal_point() const
111  { return dchar; }
112
113  char_type
114  do_thousands_sep() const
115  { return ','; }
116
117  string
118  do_grouping() const
119  { return string(); }
120};
121
122template<typename _CharT>
123void apply_formatting(const _TestCase & tc, basic_ostream<_CharT> & os)
124{
125  os.precision(tc.precision);
126  os.width(tc.width);
127  os.fill(static_cast<_CharT>(tc.fill));
128  if (tc.fixed)
129    os.setf(ios::fixed);
130  if (tc.scientific)
131    os.setf(ios::scientific);
132  if (tc.showpos)
133    os.setf(ios::showpos);
134  if (tc.showpoint)
135    os.setf(ios::showpoint);
136  if (tc.uppercase)
137    os.setf(ios::uppercase);
138  if (tc.internal)
139    os.setf(ios::internal);
140  if (tc.left)
141    os.setf(ios::left);
142  if (tc.right)
143    os.setf(ios::right);
144}
145
146void
147test01()
148{
149  bool test __attribute__((unused)) = true;
150  for (std::size_t j = 0; j<sizeof(testcases)/sizeof(testcases[0]); j++)
151    {
152      _TestCase & tc = testcases[j];
153#ifdef TEST_NUMPUT_VERBOSE
154      cout << "expect: " << tc.result << endl;
155#endif
156      // test double with char type
157      {
158        testpunct<char>* __tp = new testpunct<char>(tc.decimal);
159        ostringstream os;
160        locale __loc(os.getloc(), __tp);
161        os.imbue(__loc);
162        apply_formatting(tc, os);
163        os << tc.val;
164#ifdef TEST_NUMPUT_VERBOSE
165        cout << j << "result 1: " << os.str() << endl;
166#endif
167        VERIFY( os && os.str() == tc.result );
168      }
169      // test long double with char type
170      {
171        testpunct<char>* __tp = new testpunct<char>(tc.decimal);
172        ostringstream os;
173        locale __loc(os.getloc(), __tp);
174        os.imbue(__loc);
175        apply_formatting(tc, os);
176        os << (long double)tc.val;
177#ifdef TEST_NUMPUT_VERBOSE
178        cout << j << "result 2: " << os.str() << endl;
179#endif
180        VERIFY( os && os.str() == tc.result );
181      }
182    }
183}
184
185int
186main()
187{
188  test01();
189  return 0;
190}
191