1 // Compatibility symbols for alternate 128-bit long-double format -*- C++ -*-
2 
3 // Copyright (C) 2018-2021 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 #define _GLIBCXX_USE_CXX11_ABI 0
26 #include <locale>
27 
28 #ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
29 
30 #if ! defined __LONG_DOUBLE_IBM128__ && ! defined __LONG_DOUBLE_IEEE128__
31 #error "compatibility-ldbl-alt128.cc must only be compiled for 128-bit long double"
32 #endif
33 
34 #define C char
35 #define C_is_char
36 #include "locale-inst-numeric.h"
37 #include "locale-inst-monetary.h"
38 #include "compatibility-ldbl-facets-aliases.h"
39 
40 #ifdef _GLIBCXX_USE_WCHAR_T
41 # undef C
42 # undef C_is_char
43 # define C wchar_t
44 # include "locale-inst-numeric.h"
45 # include "locale-inst-monetary.h"
46 # include "compatibility-ldbl-facets-aliases.h"
47 # undef C
48 #endif
49 
50 #include <limits>
51 #include <functional>
52 
53 namespace std _GLIBCXX_VISIBILITY(default)
54 {
55 _GLIBCXX_BEGIN_NAMESPACE_VERSION
56 
57   // long double
58   const bool numeric_limits<long double>::is_specialized;
59   const int  numeric_limits<long double>::digits;
60   const int  numeric_limits<long double>::digits10;
61   const int  numeric_limits<long double>::max_digits10;
62   const bool numeric_limits<long double>::is_signed;
63   const bool numeric_limits<long double>::is_integer;
64   const bool numeric_limits<long double>::is_exact;
65   const int  numeric_limits<long double>::radix;
66   const int  numeric_limits<long double>::min_exponent;
67   const int  numeric_limits<long double>::min_exponent10;
68   const int  numeric_limits<long double>::max_exponent;
69   const int  numeric_limits<long double>::max_exponent10;
70   const bool numeric_limits<long double>::has_infinity;
71   const bool numeric_limits<long double>::has_quiet_NaN;
72   const bool numeric_limits<long double>::has_signaling_NaN;
73   const float_denorm_style numeric_limits<long double>::has_denorm;
74   const bool numeric_limits<long double>::has_denorm_loss;
75   const bool numeric_limits<long double>::is_iec559;
76   const bool numeric_limits<long double>::is_bounded;
77   const bool numeric_limits<long double>::is_modulo;
78   const bool numeric_limits<long double>::traps;
79   const bool numeric_limits<long double>::tinyness_before;
80   const float_round_style numeric_limits<long double>::round_style;
81 
82   template<>
83     void
__convert_to_v(const char * __s,long double & __v,ios_base::iostate & __err,const __c_locale & __cloc)84     __convert_to_v(const char* __s, long double& __v, ios_base::iostate& __err,
85 		   const __c_locale& __cloc) throw()
86     {
87       char* __sanity;
88 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
89       // Prefer strtold_l, as __strtold_l isn't prototyped in more recent
90       // glibc versions.
91       __v = strtold_l(__s, &__sanity, __cloc);
92 #else
93       __v = __strtold_l(__s, &__sanity, __cloc);
94 #endif
95 
96       // _GLIBCXX_RESOLVE_LIB_DEFECTS
97       // 23. Num_get overflow result.
98       if (__sanity == __s || *__sanity != '\0')
99 	{
100 	  __v = 0.0l;
101 	  __err = ios_base::failbit;
102 	}
103       else if (__v == numeric_limits<long double>::infinity())
104 	{
105 	  __v = numeric_limits<long double>::max();
106 	  __err = ios_base::failbit;
107 	}
108       else if (__v == -numeric_limits<long double>::infinity())
109 	{
110 	  __v = -numeric_limits<long double>::max();
111 	  __err = ios_base::failbit;
112 	}
113     }
114 
115   namespace
116   {
117     alignas(money_get<char>) char money_get_c[sizeof(money_get<char>)];
118     alignas(money_put<char>) char money_put_c[sizeof(money_put<char>)];
119     alignas(num_get<char>) char num_get_c[sizeof(num_get<char>)];
120     alignas(num_put<char>) char num_put_c[sizeof(num_put<char>)];
121 #ifdef _GLIBCXX_USE_WCHAR_T
122     alignas(money_get<wchar_t>) char money_get_w[sizeof(money_get<wchar_t>)];
123     alignas(money_put<wchar_t>) char money_put_w[sizeof(money_put<wchar_t>)];
124     alignas(num_get<wchar_t>) char num_get_w[sizeof(num_get<wchar_t>)];
125     alignas(num_put<wchar_t>) char num_put_w[sizeof(num_put<wchar_t>)];
126 #endif
127   }
128 
129   extern void
130   __locale_Impl_init_extra_ldbl128(
131       function<void(const locale::id*, const locale::facet*)>,
132       bool);
133 
134   void
_M_init_extra_ldbl128(bool classic)135   locale::_Impl::_M_init_extra_ldbl128(bool classic)
136   {
137     if (classic)
138       {
139 	_M_init_facet(new (&money_get_c) money_get<char>(1));
140 	_M_init_facet(new (&money_put_c) money_put<char>(1));
141 	_M_init_facet(new (&num_get_c) num_get<char>(1));
142 	_M_init_facet(new (&num_put_c) num_put<char>(1));
143 #ifdef _GLIBCXX_USE_WCHAR_T
144 	_M_init_facet(new (&money_get_w) money_get<wchar_t>(1));
145 	_M_init_facet(new (&money_put_w) money_put<wchar_t>(1));
146 	_M_init_facet(new (&num_get_w) num_get<wchar_t>(1));
147 	_M_init_facet(new (&num_put_w) num_put<wchar_t>(1));
148 #endif
149       }
150     else
151       {
152 	_M_init_facet(new money_get<char>);
153 	_M_init_facet(new money_put<char>);
154 	_M_init_facet(new num_get<char>);
155 	_M_init_facet(new num_put<char>);
156 #ifdef _GLIBCXX_USE_WCHAR_T
157 	_M_init_facet(new money_get<wchar_t>);
158 	_M_init_facet(new money_put<wchar_t>);
159 	_M_init_facet(new num_get<wchar_t>);
160 	_M_init_facet(new num_put<wchar_t>);
161 #endif
162       }
163 
164 #if _GLIBCXX_USE_DUAL_ABI
165     __locale_Impl_init_extra_ldbl128(
166 	[this](const locale::id* i, const facet* f) {
167 	    _M_install_facet(i, f);
168 	},
169 	classic);
170 #endif
171   }
172 
173 _GLIBCXX_END_NAMESPACE_VERSION
174 } // namespace
175 
176 #include <istream>
177 #include <ostream>
178 
179 namespace std _GLIBCXX_VISIBILITY(default)
180 {
181 _GLIBCXX_BEGIN_NAMESPACE_VERSION
182   template istream& istream::operator>>(long double&);
183   template istream& istream::_M_extract(long double&);
184   template ostream& ostream::operator<<(long double);
185   template ostream& ostream::_M_insert(long double);
186 #ifdef _GLIBCXX_USE_WCHAR_T
187   template wistream& wistream::operator>>(long double&);
188   template wistream& wistream::_M_extract(long double&);
189   template wostream& wostream::operator<<(long double);
190   template wostream& wostream::_M_insert(long double);
191 #endif
192 _GLIBCXX_END_NAMESPACE_VERSION
193 } // namespace
194 
195 #include <complex>
196 
197 namespace std _GLIBCXX_VISIBILITY(default)
198 {
199 _GLIBCXX_BEGIN_NAMESPACE_VERSION
200   template
201     basic_istream<char, char_traits<char> >&
202     operator>>(basic_istream<char, char_traits<char> >&,
203 	       complex<long double>&);
204   template
205     basic_ostream<char, char_traits<char> >&
206     operator<<(basic_ostream<char, char_traits<char> >&,
207                const complex<long double>&);
208 #ifdef _GLIBCXX_USE_WCHAR_T
209   template
210     basic_istream<wchar_t, char_traits<wchar_t> >&
211     operator>>(basic_istream<wchar_t, char_traits<wchar_t> >&,
212                complex<long double>&);
213   template
214     basic_ostream<wchar_t, char_traits<wchar_t> >&
215     operator<<(basic_ostream<wchar_t, char_traits<wchar_t> >&,
216                const complex<long double>&);
217 #endif
218 _GLIBCXX_END_NAMESPACE_VERSION
219 } // namespace
220 
221 #include <cmath>
222 #include <tr1/functional>
223 
224 // For std::tr1::hash<long double>::operator()
225 #include "../c++98/hash-long-double-tr1-aux.cc"
226 
227 // std::tr1::hash<long double>::operator()
228 // and std::hash<long double>::operator()
229 // are the same, no need to duplicate them.
230 #ifdef __LONG_DOUBLE_IBM128__
231 extern "C" size_t
232 _ZNKSt4hashIgEclEg (void)
233   __attribute__((pure))
234   __attribute__((alias ("_ZNKSt3tr14hashIgEclEg")));
235 #elif __LONG_DOUBLE_IEEE128__
236 extern "C" size_t
237 _ZNKSt4hashIu9__ieee128EclEu9__ieee128 (void)
238   __attribute__((pure))
239   __attribute__((alias ("_ZNKSt3tr14hashIu9__ieee128EclEu9__ieee128")));
240 #else
241 # error "Configuration error"
242 #endif
243 
244 #endif
245