1 /*
2  *
3  * Copyright (c) 2004
4  * John Maddock
5  *
6  * Use, modification and distribution are subject to the
7  * Boost Software License, Version 1.0. (See accompanying file
8  * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9  *
10  */
11 
12  /*
13   *   LOCATION:    see http://www.boost.org for most recent version.
14   *   FILE         regex_traits_defaults.hpp
15   *   VERSION      see <boost/version.hpp>
16   *   DESCRIPTION: Declares API's for access to regex_traits default properties.
17   */
18 
19 #ifndef BOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED
20 #define BOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED
21 
22 #ifdef BOOST_HAS_ABI_HEADERS
23 #  include BOOST_ABI_PREFIX
24 #endif
25 
26 #ifndef BOOST_REGEX_SYNTAX_TYPE_HPP
27 #include <boost/regex/v4/syntax_type.hpp>
28 #endif
29 #ifndef BOOST_REGEX_ERROR_TYPE_HPP
30 #include <boost/regex/v4/error_type.hpp>
31 #endif
32 
33 #ifdef BOOST_NO_STDC_NAMESPACE
34 namespace std{
35    using ::strlen;
36 }
37 #endif
38 
39 namespace boost{ namespace re_detail{
40 
41 
42 //
43 // helpers to suppress warnings:
44 //
45 template <class charT>
is_extended(charT c)46 inline bool is_extended(charT c)
47 { return c > 256; }
is_extended(char)48 inline bool is_extended(char)
49 { return false; }
50 
51 
52 BOOST_REGEX_DECL const char* BOOST_REGEX_CALL get_default_syntax(regex_constants::syntax_type n);
53 BOOST_REGEX_DECL const char* BOOST_REGEX_CALL get_default_error_string(regex_constants::error_type n);
54 BOOST_REGEX_DECL regex_constants::syntax_type BOOST_REGEX_CALL get_default_syntax_type(char c);
55 BOOST_REGEX_DECL regex_constants::escape_syntax_type BOOST_REGEX_CALL get_default_escape_syntax_type(char c);
56 
57 // is charT c a combining character?
58 BOOST_REGEX_DECL bool BOOST_REGEX_CALL is_combining_implementation(uint_least16_t s);
59 
60 template <class charT>
is_combining(charT c)61 inline bool is_combining(charT c)
62 {
63    return (c <= static_cast<charT>(0)) ? false : ((c >= static_cast<charT>((std::numeric_limits<uint_least16_t>::max)())) ? false : is_combining_implementation(static_cast<unsigned short>(c)));
64 }
65 template <>
is_combining(char)66 inline bool is_combining<char>(char)
67 {
68    return false;
69 }
70 template <>
is_combining(signed char)71 inline bool is_combining<signed char>(signed char)
72 {
73    return false;
74 }
75 template <>
is_combining(unsigned char)76 inline bool is_combining<unsigned char>(unsigned char)
77 {
78    return false;
79 }
80 #ifndef __HP_aCC
81 #ifdef _MSC_VER
82 template<>
is_combining(wchar_t c)83 inline bool is_combining<wchar_t>(wchar_t c)
84 {
85    return is_combining_implementation(static_cast<unsigned short>(c));
86 }
87 #elif !defined(__DECCXX) && !defined(__osf__) && !defined(__OSF__) && defined(WCHAR_MIN) && (WCHAR_MIN == 0) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
88 #if defined(WCHAR_MAX) && (WCHAR_MAX <= USHRT_MAX)
89 template<>
is_combining(wchar_t c)90 inline bool is_combining<wchar_t>(wchar_t c)
91 {
92    return is_combining_implementation(static_cast<unsigned short>(c));
93 }
94 #else
95 template<>
is_combining(wchar_t c)96 inline bool is_combining<wchar_t>(wchar_t c)
97 {
98    return (c >= (std::numeric_limits<uint_least16_t>::max)()) ? false : is_combining_implementation(static_cast<unsigned short>(c));
99 }
100 #endif
101 #endif
102 #endif
103 
104 //
105 // is a charT c a line separator?
106 //
107 template <class charT>
is_separator(charT c)108 inline bool is_separator(charT c)
109 {
110    return BOOST_REGEX_MAKE_BOOL(
111       (c == static_cast<charT>('\n'))
112       || (c == static_cast<charT>('\r'))
113       || (c == static_cast<charT>('\f'))
114       || (static_cast<boost::uint16_t>(c) == 0x2028u)
115       || (static_cast<boost::uint16_t>(c) == 0x2029u)
116       || (static_cast<boost::uint16_t>(c) == 0x85u));
117 }
118 template <>
is_separator(char c)119 inline bool is_separator<char>(char c)
120 {
121    return BOOST_REGEX_MAKE_BOOL((c == '\n') || (c == '\r') || (c == '\f'));
122 }
123 
124 //
125 // get a default collating element:
126 //
127 BOOST_REGEX_DECL std::string BOOST_REGEX_CALL lookup_default_collate_name(const std::string& name);
128 
129 //
130 // get the id of a character clasification, the individual
131 // traits classes then transform that id into a bitmask:
132 //
133 template <class charT>
134 struct character_pointer_range
135 {
136    const charT* p1;
137    const charT* p2;
138 
operator <boost::re_detail::character_pointer_range139    bool operator < (const character_pointer_range& r)const
140    {
141       return std::lexicographical_compare(p1, p2, r.p1, r.p2);
142    }
operator ==boost::re_detail::character_pointer_range143    bool operator == (const character_pointer_range& r)const
144    {
145       return ((p2 - p1) == (r.p2 - r.p1)) && std::equal(p1, p2, r.p1);
146    }
147 };
148 template <class charT>
get_default_class_id(const charT * p1,const charT * p2)149 int get_default_class_id(const charT* p1, const charT* p2)
150 {
151    static const charT data[72] = {
152       'a', 'l', 'n', 'u', 'm',
153       'a', 'l', 'p', 'h', 'a',
154       'b', 'l', 'a', 'n', 'k',
155       'c', 'n', 't', 'r', 'l',
156       'd', 'i', 'g', 'i', 't',
157       'g', 'r', 'a', 'p', 'h',
158       'l', 'o', 'w', 'e', 'r',
159       'p', 'r', 'i', 'n', 't',
160       'p', 'u', 'n', 'c', 't',
161       's', 'p', 'a', 'c', 'e',
162       'u', 'n', 'i', 'c', 'o', 'd', 'e',
163       'u', 'p', 'p', 'e', 'r',
164       'w', 'o', 'r', 'd',
165       'x', 'd', 'i', 'g', 'i', 't',
166    };
167 
168    static const character_pointer_range<charT> ranges[19] =
169    {
170       {data+0, data+5,}, // alnum
171       {data+5, data+10,}, // alpha
172       {data+10, data+15,}, // blank
173       {data+15, data+20,}, // cntrl
174       {data+20, data+21,}, // d
175       {data+20, data+25,}, // digit
176       {data+25, data+30,}, // graph
177       {data+30, data+31,}, // l
178       {data+30, data+35,}, // lower
179       {data+35, data+40,}, // print
180       {data+40, data+45,}, // punct
181       {data+45, data+46,}, // s
182       {data+45, data+50,}, // space
183       {data+57, data+58,}, // u
184       {data+50, data+57,}, // unicode
185       {data+57, data+62,}, // upper
186       {data+62, data+63,}, // w
187       {data+62, data+66,}, // word
188       {data+66, data+72,}, // xdigit
189    };
190    static const character_pointer_range<charT>* ranges_begin = ranges;
191    static const character_pointer_range<charT>* ranges_end = ranges + (sizeof(ranges)/sizeof(ranges[0]));
192 
193    character_pointer_range<charT> t = { p1, p2, };
194    const character_pointer_range<charT>* p = std::lower_bound(ranges_begin, ranges_end, t);
195    if((p != ranges_end) && (t == *p))
196       return static_cast<int>(p - ranges);
197    return -1;
198 }
199 
200 //
201 // helper functions:
202 //
203 template <class charT>
global_length(const charT * p)204 std::ptrdiff_t global_length(const charT* p)
205 {
206    std::ptrdiff_t n = 0;
207    while(*p)
208    {
209       ++p;
210       ++n;
211    }
212    return n;
213 }
214 template<>
global_length(const char * p)215 inline std::ptrdiff_t global_length<char>(const char* p)
216 {
217    return (std::strlen)(p);
218 }
219 #ifndef BOOST_NO_WREGEX
220 template<>
global_length(const wchar_t * p)221 inline std::ptrdiff_t global_length<wchar_t>(const wchar_t* p)
222 {
223    return (std::wcslen)(p);
224 }
225 #endif
226 template <class charT>
global_lower(charT c)227 inline charT BOOST_REGEX_CALL global_lower(charT c)
228 {
229    return c;
230 }
231 template <class charT>
global_upper(charT c)232 inline charT BOOST_REGEX_CALL global_upper(charT c)
233 {
234    return c;
235 }
236 
237 BOOST_REGEX_DECL char BOOST_REGEX_CALL do_global_lower(char c);
238 BOOST_REGEX_DECL char BOOST_REGEX_CALL do_global_upper(char c);
239 #ifndef BOOST_NO_WREGEX
240 BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL do_global_lower(wchar_t c);
241 BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL do_global_upper(wchar_t c);
242 #endif
243 #ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
244 BOOST_REGEX_DECL unsigned short BOOST_REGEX_CALL do_global_lower(unsigned short c);
245 BOOST_REGEX_DECL unsigned short BOOST_REGEX_CALL do_global_upper(unsigned short c);
246 #endif
247 //
248 // This sucks: declare template specialisations of global_lower/global_upper
249 // that just forward to the non-template implementation functions.  We do
250 // this because there is one compiler (Compaq Tru64 C++) that doesn't seem
251 // to differentiate between templates and non-template overloads....
252 // what's more, the primary template, plus all overloads have to be
253 // defined in the same translation unit (if one is inline they all must be)
254 // otherwise the "local template instantiation" compiler option can pick
255 // the wrong instantiation when linking:
256 //
global_lower(char c)257 template<> inline char BOOST_REGEX_CALL global_lower<char>(char c){ return do_global_lower(c); }
global_upper(char c)258 template<> inline char BOOST_REGEX_CALL global_upper<char>(char c){ return do_global_upper(c); }
259 #ifndef BOOST_NO_WREGEX
global_lower(wchar_t c)260 template<> inline wchar_t BOOST_REGEX_CALL global_lower<wchar_t>(wchar_t c){ return do_global_lower(c); }
global_upper(wchar_t c)261 template<> inline wchar_t BOOST_REGEX_CALL global_upper<wchar_t>(wchar_t c){ return do_global_upper(c); }
262 #endif
263 #ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
global_lower(unsigned short c)264 template<> inline unsigned short BOOST_REGEX_CALL global_lower<unsigned short>(unsigned short c){ return do_global_lower(c); }
global_upper(unsigned short c)265 template<> inline unsigned short BOOST_REGEX_CALL global_upper<unsigned short>(unsigned short c){ return do_global_upper(c); }
266 #endif
267 
268 template <class charT>
global_value(charT c)269 int global_value(charT c)
270 {
271    static const charT zero = '0';
272    static const charT nine = '9';
273    static const charT a = 'a';
274    static const charT f = 'f';
275    static const charT A = 'A';
276    static const charT F = 'F';
277 
278    if(c > f) return -1;
279    if(c >= a) return 10 + (c - a);
280    if(c > F) return -1;
281    if(c >= A) return 10 + (c - A);
282    if(c > nine) return -1;
283    if(c >= zero) return c - zero;
284    return -1;
285 }
286 template <class charT, class traits>
global_toi(const charT * & p1,const charT * p2,int radix,const traits & t)287 int global_toi(const charT*& p1, const charT* p2, int radix, const traits& t)
288 {
289    (void)t; // warning suppression
290    int next_value = t.value(*p1, radix);
291    if((p1 == p2) || (next_value < 0) || (next_value >= radix))
292       return -1;
293    int result = 0;
294    while(p1 != p2)
295    {
296       next_value = t.value(*p1, radix);
297       if((next_value < 0) || (next_value >= radix))
298          break;
299       result *= radix;
300       result += next_value;
301       ++p1;
302    }
303    return result;
304 }
305 
306 } // re_detail
307 } // boost
308 
309 #ifdef BOOST_HAS_ABI_HEADERS
310 #  include BOOST_ABI_SUFFIX
311 #endif
312 
313 #endif
314