File Coverage

/usr/include/c++/5/bits/locale_classes.tcc
Criterion Covered Total %
statement 0 6 0.0
branch 0 6 0.0
condition n/a
subroutine n/a
pod n/a
total 0 12 0.0


line stmt bran cond sub pod time code
1             // Locale support -*- C++ -*-
2              
3             // Copyright (C) 2007-2015 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             // .
24              
25             /** @file bits/locale_classes.tcc
26             * This is an internal header file, included by other library headers.
27             * Do not attempt to use it directly. @headername{locale}
28             */
29              
30             //
31             // ISO C++ 14882: 22.1 Locales
32             //
33              
34             #ifndef _LOCALE_CLASSES_TCC
35             #define _LOCALE_CLASSES_TCC 1
36              
37             #pragma GCC system_header
38              
39             namespace std _GLIBCXX_VISIBILITY(default)
40             {
41             _GLIBCXX_BEGIN_NAMESPACE_VERSION
42              
43             template
44             locale::
45             locale(const locale& __other, _Facet* __f)
46             {
47             _M_impl = new _Impl(*__other._M_impl, 1);
48              
49             __try
50             { _M_impl->_M_install_facet(&_Facet::id, __f); }
51             __catch(...)
52             {
53             _M_impl->_M_remove_reference();
54             __throw_exception_again;
55             }
56             delete [] _M_impl->_M_names[0];
57             _M_impl->_M_names[0] = 0; // Unnamed.
58             }
59              
60             template
61             locale
62             locale::
63             combine(const locale& __other) const
64             {
65             _Impl* __tmp = new _Impl(*_M_impl, 1);
66             __try
67             {
68             __tmp->_M_replace_facet(__other._M_impl, &_Facet::id);
69             }
70             __catch(...)
71             {
72             __tmp->_M_remove_reference();
73             __throw_exception_again;
74             }
75             return locale(__tmp);
76             }
77              
78             template
79             bool
80             locale::
81             operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1,
82             const basic_string<_CharT, _Traits, _Alloc>& __s2) const
83             {
84             typedef std::collate<_CharT> __collate_type;
85             const __collate_type& __collate = use_facet<__collate_type>(*this);
86             return (__collate.compare(__s1.data(), __s1.data() + __s1.length(),
87             __s2.data(), __s2.data() + __s2.length()) < 0);
88             }
89              
90             /**
91             * @brief Test for the presence of a facet.
92             * @ingroup locales
93             *
94             * has_facet tests the locale argument for the presence of the facet type
95             * provided as the template parameter. Facets derived from the facet
96             * parameter will also return true.
97             *
98             * @tparam _Facet The facet type to test the presence of.
99             * @param __loc The locale to test.
100             * @return true if @p __loc contains a facet of type _Facet, else false.
101             */
102             template
103             bool
104             has_facet(const locale& __loc) throw()
105             {
106             const size_t __i = _Facet::id._M_id();
107             const locale::facet** __facets = __loc._M_impl->_M_facets;
108             return (__i < __loc._M_impl->_M_facets_size
109             #if __cpp_rtti
110             && dynamic_cast(__facets[__i]));
111             #else
112             && static_cast(__facets[__i]));
113             #endif
114             }
115              
116             /**
117             * @brief Return a facet.
118             * @ingroup locales
119             *
120             * use_facet looks for and returns a reference to a facet of type Facet
121             * where Facet is the template parameter. If has_facet(locale) is true,
122             * there is a suitable facet to return. It throws std::bad_cast if the
123             * locale doesn't contain a facet of type Facet.
124             *
125             * @tparam _Facet The facet type to access.
126             * @param __loc The locale to use.
127             * @return Reference to facet of type Facet.
128             * @throw std::bad_cast if @p __loc doesn't contain a facet of type _Facet.
129             */
130             template
131             const _Facet&
132 0           use_facet(const locale& __loc)
133             {
134 0           const size_t __i = _Facet::id._M_id();
135 0           const locale::facet** __facets = __loc._M_impl->_M_facets;
136 0 0         if (__i >= __loc._M_impl->_M_facets_size || !__facets[__i])
    0          
137 0           __throw_bad_cast();
138             #if __cpp_rtti
139 0 0         return dynamic_cast(*__facets[__i]);
140             #else
141             return static_cast(*__facets[__i]);
142             #endif
143             }
144              
145              
146             // Generic version does nothing.
147             template
148             int
149             collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const throw ()
150             { return 0; }
151              
152             // Generic version does nothing.
153             template
154             size_t
155             collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const throw ()
156             { return 0; }
157              
158             template
159             int
160             collate<_CharT>::
161             do_compare(const _CharT* __lo1, const _CharT* __hi1,
162             const _CharT* __lo2, const _CharT* __hi2) const
163             {
164             // strcoll assumes zero-terminated strings so we make a copy
165             // and then put a zero at the end.
166             const string_type __one(__lo1, __hi1);
167             const string_type __two(__lo2, __hi2);
168              
169             const _CharT* __p = __one.c_str();
170             const _CharT* __pend = __one.data() + __one.length();
171             const _CharT* __q = __two.c_str();
172             const _CharT* __qend = __two.data() + __two.length();
173              
174             // strcoll stops when it sees a nul character so we break
175             // the strings into zero-terminated substrings and pass those
176             // to strcoll.
177             for (;;)
178             {
179             const int __res = _M_compare(__p, __q);
180             if (__res)
181             return __res;
182              
183             __p += char_traits<_CharT>::length(__p);
184             __q += char_traits<_CharT>::length(__q);
185             if (__p == __pend && __q == __qend)
186             return 0;
187             else if (__p == __pend)
188             return -1;
189             else if (__q == __qend)
190             return 1;
191              
192             __p++;
193             __q++;
194             }
195             }
196              
197             template
198             typename collate<_CharT>::string_type
199             collate<_CharT>::
200             do_transform(const _CharT* __lo, const _CharT* __hi) const
201             {
202             string_type __ret;
203              
204             // strxfrm assumes zero-terminated strings so we make a copy
205             const string_type __str(__lo, __hi);
206              
207             const _CharT* __p = __str.c_str();
208             const _CharT* __pend = __str.data() + __str.length();
209              
210             size_t __len = (__hi - __lo) * 2;
211              
212             _CharT* __c = new _CharT[__len];
213              
214             __try
215             {
216             // strxfrm stops when it sees a nul character so we break
217             // the string into zero-terminated substrings and pass those
218             // to strxfrm.
219             for (;;)
220             {
221             // First try a buffer perhaps big enough.
222             size_t __res = _M_transform(__c, __p, __len);
223             // If the buffer was not large enough, try again with the
224             // correct size.
225             if (__res >= __len)
226             {
227             __len = __res + 1;
228             delete [] __c, __c = 0;
229             __c = new _CharT[__len];
230             __res = _M_transform(__c, __p, __len);
231             }
232              
233             __ret.append(__c, __res);
234             __p += char_traits<_CharT>::length(__p);
235             if (__p == __pend)
236             break;
237              
238             __p++;
239             __ret.push_back(_CharT());
240             }
241             }
242             __catch(...)
243             {
244             delete [] __c;
245             __throw_exception_again;
246             }
247              
248             delete [] __c;
249              
250             return __ret;
251             }
252              
253             template
254             long
255             collate<_CharT>::
256             do_hash(const _CharT* __lo, const _CharT* __hi) const
257             {
258             unsigned long __val = 0;
259             for (; __lo < __hi; ++__lo)
260             __val =
261             *__lo + ((__val << 7)
262             | (__val >> (__gnu_cxx::__numeric_traits::
263             __digits - 7)));
264             return static_cast(__val);
265             }
266              
267             // Inhibit implicit instantiations for required instantiations,
268             // which are defined via explicit instantiations elsewhere.
269             #if _GLIBCXX_EXTERN_TEMPLATE
270             extern template class collate;
271             extern template class collate_byname;
272              
273             extern template
274             const collate&
275             use_facet >(const locale&);
276              
277             extern template
278             bool
279             has_facet >(const locale&);
280              
281             #ifdef _GLIBCXX_USE_WCHAR_T
282             extern template class collate;
283             extern template class collate_byname;
284              
285             extern template
286             const collate&
287             use_facet >(const locale&);
288              
289             extern template
290             bool
291             has_facet >(const locale&);
292             #endif
293             #endif
294              
295             _GLIBCXX_END_NAMESPACE_VERSION
296             } // namespace std
297              
298             #endif