CPPXT-104 - Add exception handling to integer conversions
[shibboleth/cpp-xmltooling.git] / xmltooling / char_traits.h
1 /**
2  * Licensed to the University Corporation for Advanced Internet
3  * Development, Inc. (UCAID) under one or more contributor license
4  * agreements. See the NOTICE file distributed with this work for
5  * additional information regarding copyright ownership.
6  *
7  * UCAID licenses this file to you under the Apache License,
8  * Version 2.0 (the "License"); you may not use this file except
9  * in compliance with the License. You may obtain a copy of the
10  * License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
17  * either express or implied. See the License for the specific
18  * language governing permissions and limitations under the License.
19  */
20
21 /**
22  * @file xmltooling/char_traits.h
23  *
24  * Traits template for basic_string<unsigned short> instantiation on strict compilers.
25  */
26
27 #ifndef __xmltooling_chartraits_h__
28 #define __xmltooling_chartraits_h__
29
30 #include <xmltooling/base.h>
31
32 #include <cstring>
33 #include <algorithm>
34
35 namespace xmltooling {
36
37   /// @cond OFF
38
39   template <class _CharT>
40     struct _Char_types
41     {
42       typedef unsigned long   int_type;
43       typedef std::streampos  pos_type;
44       typedef std::streamoff  off_type;
45       typedef std::mbstate_t  state_type;
46     };
47
48
49   template<typename _CharT>
50     struct char_traits
51     {
52       typedef _CharT                                    char_type;
53       typedef typename _Char_types<_CharT>::int_type    int_type;
54       typedef typename _Char_types<_CharT>::pos_type    pos_type;
55       typedef typename _Char_types<_CharT>::off_type    off_type;
56       typedef typename _Char_types<_CharT>::state_type  state_type;
57
58       static void
59       assign(char_type& __c1, const char_type& __c2)
60       { __c1 = __c2; }
61
62       static bool
63       eq(const char_type& __c1, const char_type& __c2)
64       { return __c1 == __c2; }
65
66       static bool
67       lt(const char_type& __c1, const char_type& __c2)
68       { return __c1 < __c2; }
69
70       static int
71       compare(const char_type* __s1, const char_type* __s2, std::size_t __n);
72
73       static std::size_t
74       length(const char_type* __s);
75
76       static const char_type*
77       find(const char_type* __s, std::size_t __n, const char_type& __a);
78
79       static char_type*
80       move(char_type* __s1, const char_type* __s2, std::size_t __n);
81
82       static char_type*
83       copy(char_type* __s1, const char_type* __s2, std::size_t __n);
84
85       static char_type*
86       assign(char_type* __s, std::size_t __n, char_type __a);
87
88       static char_type
89       to_char_type(const int_type& __c)
90       { return static_cast<char_type>(__c); }
91
92       static int_type
93       to_int_type(const char_type& __c)
94       { return static_cast<int_type>(__c); }
95
96       static bool
97       eq_int_type(const int_type& __c1, const int_type& __c2)
98       { return __c1 == __c2; }
99
100       static int_type
101       eof()
102       { return static_cast<int_type>(EOF); }
103
104       static int_type
105       not_eof(const int_type& __c)
106       { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); }
107     };
108
109   template<typename _CharT>
110     int
111     char_traits<_CharT>::
112     compare(const char_type* __s1, const char_type* __s2, std::size_t __n)
113     {
114       for (size_t __i = 0; __i < __n; ++__i)
115     if (lt(__s1[__i], __s2[__i]))
116       return -1;
117     else if (lt(__s2[__i], __s1[__i]))
118       return 1;
119       return 0;
120     }
121
122   template<typename _CharT>
123     std::size_t
124     char_traits<_CharT>::
125     length(const char_type* __p)
126     {
127       std::size_t __i = 0;
128       while (!eq(__p[__i], char_type()))
129         ++__i;
130       return __i;
131     }
132
133   template<typename _CharT>
134     const typename char_traits<_CharT>::char_type*
135     char_traits<_CharT>::
136     find(const char_type* __s, std::size_t __n, const char_type& __a)
137     {
138       for (std::size_t __i = 0; __i < __n; ++__i)
139         if (eq(__s[__i], __a))
140           return __s + __i;
141       return 0;
142     }
143
144   template<typename _CharT>
145     typename char_traits<_CharT>::char_type*
146     char_traits<_CharT>::
147     move(char_type* __s1, const char_type* __s2, std::size_t __n)
148     {
149       return static_cast<_CharT*>(std::memmove(__s1, __s2,
150                            __n * sizeof(char_type)));
151     }
152
153   template<typename _CharT>
154     typename char_traits<_CharT>::char_type*
155     char_traits<_CharT>::
156     copy(char_type* __s1, const char_type* __s2, std::size_t __n)
157     {
158       std::copy(__s2, __s2 + __n, __s1);
159       return __s1;
160     }
161
162   template<typename _CharT>
163     typename char_traits<_CharT>::char_type*
164     char_traits<_CharT>::
165     assign(char_type* __s, std::size_t __n, char_type __a)
166     {
167       std::fill_n(__s, __n, __a);
168       return __s;
169     }
170
171     /// @endcond
172 }
173
174 #endif // __xmltooling_chartraits_h__