blob: 2b4fc288a64c9fc54c3726acc908b8a0471ad30f [file] [log] [blame]
Jeff Thompson86b6d642013-10-17 15:01:56 -07001/*
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 <ndnboost/version.hpp>
16 * DESCRIPTION: Declares API's for access to regex_traits default properties.
17 */
18
19#ifndef NDNBOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED
20#define NDNBOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED
21
22#ifdef NDNBOOST_MSVC
23#pragma warning(push)
24#pragma warning(disable: 4103)
25#endif
26#ifdef NDNBOOST_HAS_ABI_HEADERS
27# include NDNBOOST_ABI_PREFIX
28#endif
29#ifdef NDNBOOST_MSVC
30#pragma warning(pop)
31#endif
32
33#ifndef NDNBOOST_REGEX_SYNTAX_TYPE_HPP
34#include <ndnboost/regex/v4/syntax_type.hpp>
35#endif
36#ifndef NDNBOOST_REGEX_ERROR_TYPE_HPP
37#include <ndnboost/regex/v4/error_type.hpp>
38#endif
39
40#ifdef NDNBOOST_NO_STDC_NAMESPACE
41namespace std{
42 using ::strlen;
43}
44#endif
45
46namespace ndnboost{ namespace re_detail{
47
48
49//
50// helpers to suppress warnings:
51//
52template <class charT>
53inline bool is_extended(charT c)
54{ return c > 256; }
55inline bool is_extended(char)
56{ return false; }
57
58
59NDNBOOST_REGEX_DECL const char* NDNBOOST_REGEX_CALL get_default_syntax(regex_constants::syntax_type n);
60NDNBOOST_REGEX_DECL const char* NDNBOOST_REGEX_CALL get_default_error_string(regex_constants::error_type n);
61NDNBOOST_REGEX_DECL regex_constants::syntax_type NDNBOOST_REGEX_CALL get_default_syntax_type(char c);
62NDNBOOST_REGEX_DECL regex_constants::escape_syntax_type NDNBOOST_REGEX_CALL get_default_escape_syntax_type(char c);
63
64// is charT c a combining character?
65NDNBOOST_REGEX_DECL bool NDNBOOST_REGEX_CALL is_combining_implementation(uint_least16_t s);
66
67template <class charT>
68inline bool is_combining(charT c)
69{
70 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)));
71}
72template <>
73inline bool is_combining<char>(char)
74{
75 return false;
76}
77template <>
78inline bool is_combining<signed char>(signed char)
79{
80 return false;
81}
82template <>
83inline bool is_combining<unsigned char>(unsigned char)
84{
85 return false;
86}
87#if !defined(__hpux) && !defined(__WINSCW__) // can't use WCHAR_MAX/MIN in pp-directives
88#ifdef _MSC_VER
89template<>
90inline bool is_combining<wchar_t>(wchar_t c)
91{
92 return is_combining_implementation(static_cast<unsigned short>(c));
93}
94#elif !defined(__DECCXX) && !defined(__osf__) && !defined(__OSF__) && defined(WCHAR_MIN) && (WCHAR_MIN == 0) && !defined(NDNBOOST_NO_INTRINSIC_WCHAR_T)
95#if defined(WCHAR_MAX) && (WCHAR_MAX <= USHRT_MAX)
96template<>
97inline bool is_combining<wchar_t>(wchar_t c)
98{
99 return is_combining_implementation(static_cast<unsigned short>(c));
100}
101#else
102template<>
103inline bool is_combining<wchar_t>(wchar_t c)
104{
105 return (c >= (std::numeric_limits<uint_least16_t>::max)()) ? false : is_combining_implementation(static_cast<unsigned short>(c));
106}
107#endif
108#endif
109#endif
110
111//
112// is a charT c a line separator?
113//
114template <class charT>
115inline bool is_separator(charT c)
116{
117 return NDNBOOST_REGEX_MAKE_BOOL(
118 (c == static_cast<charT>('\n'))
119 || (c == static_cast<charT>('\r'))
120 || (c == static_cast<charT>('\f'))
121 || (static_cast<ndnboost::uint16_t>(c) == 0x2028u)
122 || (static_cast<ndnboost::uint16_t>(c) == 0x2029u)
123 || (static_cast<ndnboost::uint16_t>(c) == 0x85u));
124}
125template <>
126inline bool is_separator<char>(char c)
127{
128 return NDNBOOST_REGEX_MAKE_BOOL((c == '\n') || (c == '\r') || (c == '\f'));
129}
130
131//
132// get a default collating element:
133//
134NDNBOOST_REGEX_DECL std::string NDNBOOST_REGEX_CALL lookup_default_collate_name(const std::string& name);
135
136//
137// get the state_id of a character clasification, the individual
138// traits classes then transform that state_id into a bitmask:
139//
140template <class charT>
141struct character_pointer_range
142{
143 const charT* p1;
144 const charT* p2;
145
146 bool operator < (const character_pointer_range& r)const
147 {
148 return std::lexicographical_compare(p1, p2, r.p1, r.p2);
149 }
150 bool operator == (const character_pointer_range& r)const
151 {
152 // Not only do we check that the ranges are of equal size before
153 // calling std::equal, but there is no other algorithm available:
154 // not even a non-standard MS one. So forward to unchecked_equal
155 // in the MS case.
156 return ((p2 - p1) == (r.p2 - r.p1)) && re_detail::equal(p1, p2, r.p1);
157 }
158};
159template <class charT>
160int get_default_class_id(const charT* p1, const charT* p2)
161{
162 static const charT data[73] = {
163 'a', 'l', 'n', 'u', 'm',
164 'a', 'l', 'p', 'h', 'a',
165 'b', 'l', 'a', 'n', 'k',
166 'c', 'n', 't', 'r', 'l',
167 'd', 'i', 'g', 'i', 't',
168 'g', 'r', 'a', 'p', 'h',
169 'l', 'o', 'w', 'e', 'r',
170 'p', 'r', 'i', 'n', 't',
171 'p', 'u', 'n', 'c', 't',
172 's', 'p', 'a', 'c', 'e',
173 'u', 'n', 'i', 'c', 'o', 'd', 'e',
174 'u', 'p', 'p', 'e', 'r',
175 'v',
176 'w', 'o', 'r', 'd',
177 'x', 'd', 'i', 'g', 'i', 't',
178 };
179
180 static const character_pointer_range<charT> ranges[21] =
181 {
182 {data+0, data+5,}, // alnum
183 {data+5, data+10,}, // alpha
184 {data+10, data+15,}, // blank
185 {data+15, data+20,}, // cntrl
186 {data+20, data+21,}, // d
187 {data+20, data+25,}, // digit
188 {data+25, data+30,}, // graph
189 {data+29, data+30,}, // h
190 {data+30, data+31,}, // l
191 {data+30, data+35,}, // lower
192 {data+35, data+40,}, // print
193 {data+40, data+45,}, // punct
194 {data+45, data+46,}, // s
195 {data+45, data+50,}, // space
196 {data+57, data+58,}, // u
197 {data+50, data+57,}, // unicode
198 {data+57, data+62,}, // upper
199 {data+62, data+63,}, // v
200 {data+63, data+64,}, // w
201 {data+63, data+67,}, // word
202 {data+67, data+73,}, // xdigit
203 };
204 static const character_pointer_range<charT>* ranges_begin = ranges;
205 static const character_pointer_range<charT>* ranges_end = ranges + (sizeof(ranges)/sizeof(ranges[0]));
206
207 character_pointer_range<charT> t = { p1, p2, };
208 const character_pointer_range<charT>* p = std::lower_bound(ranges_begin, ranges_end, t);
209 if((p != ranges_end) && (t == *p))
210 return static_cast<int>(p - ranges);
211 return -1;
212}
213
214//
215// helper functions:
216//
217template <class charT>
218std::ptrdiff_t global_length(const charT* p)
219{
220 std::ptrdiff_t n = 0;
221 while(*p)
222 {
223 ++p;
224 ++n;
225 }
226 return n;
227}
228template<>
229inline std::ptrdiff_t global_length<char>(const char* p)
230{
231 return (std::strlen)(p);
232}
233#ifndef NDNBOOST_NO_WREGEX
234template<>
235inline std::ptrdiff_t global_length<wchar_t>(const wchar_t* p)
236{
237 return (std::wcslen)(p);
238}
239#endif
240template <class charT>
241inline charT NDNBOOST_REGEX_CALL global_lower(charT c)
242{
243 return c;
244}
245template <class charT>
246inline charT NDNBOOST_REGEX_CALL global_upper(charT c)
247{
248 return c;
249}
250
251NDNBOOST_REGEX_DECL char NDNBOOST_REGEX_CALL do_global_lower(char c);
252NDNBOOST_REGEX_DECL char NDNBOOST_REGEX_CALL do_global_upper(char c);
253#ifndef NDNBOOST_NO_WREGEX
254NDNBOOST_REGEX_DECL wchar_t NDNBOOST_REGEX_CALL do_global_lower(wchar_t c);
255NDNBOOST_REGEX_DECL wchar_t NDNBOOST_REGEX_CALL do_global_upper(wchar_t c);
256#endif
257#ifdef NDNBOOST_REGEX_HAS_OTHER_WCHAR_T
258NDNBOOST_REGEX_DECL unsigned short NDNBOOST_REGEX_CALL do_global_lower(unsigned short c);
259NDNBOOST_REGEX_DECL unsigned short NDNBOOST_REGEX_CALL do_global_upper(unsigned short c);
260#endif
261//
262// This sucks: declare template specialisations of global_lower/global_upper
263// that just forward to the non-template implementation functions. We do
264// this because there is one compiler (Compaq Tru64 C++) that doesn't seem
265// to differentiate between templates and non-template overloads....
266// what's more, the primary template, plus all overloads have to be
267// defined in the same translation unit (if one is inline they all must be)
268// otherwise the "local template instantiation" compiler option can pick
269// the wrong instantiation when linking:
270//
271template<> inline char NDNBOOST_REGEX_CALL global_lower<char>(char c){ return do_global_lower(c); }
272template<> inline char NDNBOOST_REGEX_CALL global_upper<char>(char c){ return do_global_upper(c); }
273#ifndef NDNBOOST_NO_WREGEX
274template<> inline wchar_t NDNBOOST_REGEX_CALL global_lower<wchar_t>(wchar_t c){ return do_global_lower(c); }
275template<> inline wchar_t NDNBOOST_REGEX_CALL global_upper<wchar_t>(wchar_t c){ return do_global_upper(c); }
276#endif
277#ifdef NDNBOOST_REGEX_HAS_OTHER_WCHAR_T
278template<> inline unsigned short NDNBOOST_REGEX_CALL global_lower<unsigned short>(unsigned short c){ return do_global_lower(c); }
279template<> inline unsigned short NDNBOOST_REGEX_CALL global_upper<unsigned short>(unsigned short c){ return do_global_upper(c); }
280#endif
281
282template <class charT>
283int global_value(charT c)
284{
285 static const charT zero = '0';
286 static const charT nine = '9';
287 static const charT a = 'a';
288 static const charT f = 'f';
289 static const charT A = 'A';
290 static const charT F = 'F';
291
292 if(c > f) return -1;
293 if(c >= a) return 10 + (c - a);
294 if(c > F) return -1;
295 if(c >= A) return 10 + (c - A);
296 if(c > nine) return -1;
297 if(c >= zero) return c - zero;
298 return -1;
299}
300template <class charT, class traits>
301int global_toi(const charT*& p1, const charT* p2, int radix, const traits& t)
302{
303 (void)t; // warning suppression
304 int next_value = t.value(*p1, radix);
305 if((p1 == p2) || (next_value < 0) || (next_value >= radix))
306 return -1;
307 int result = 0;
308 while(p1 != p2)
309 {
310 next_value = t.value(*p1, radix);
311 if((next_value < 0) || (next_value >= radix))
312 break;
313 result *= radix;
314 result += next_value;
315 ++p1;
316 }
317 return result;
318}
319
320template <class charT>
321inline const charT* get_escape_R_string()
322{
323#ifdef NDNBOOST_MSVC
324# pragma warning(push)
325# pragma warning(disable:4309 4245)
326#endif
327 static const charT e1[] = { '(', '?', '>', '\x0D', '\x0A', '?',
328 '|', '[', '\x0A', '\x0B', '\x0C', static_cast<unsigned char>('\x85'), '\\', 'x', '{', '2', '0', '2', '8', '}',
329 '\\', 'x', '{', '2', '0', '2', '9', '}', ']', ')', '\0' };
330 static const charT e2[] = { '(', '?', '>', '\x0D', '\x0A', '?',
331 '|', '[', '\x0A', '\x0B', '\x0C', static_cast<unsigned char>('\x85'), ']', ')', '\0' };
332
333 charT c = static_cast<charT>(0x2029u);
334 bool b = (static_cast<unsigned>(c) == 0x2029u);
335
336 return (b ? e1 : e2);
337#ifdef NDNBOOST_MSVC
338# pragma warning(pop)
339#endif
340}
341
342template <>
343inline const char* get_escape_R_string<char>()
344{
345#ifdef NDNBOOST_MSVC
346# pragma warning(push)
347# pragma warning(disable:4309)
348#endif
349 static const char e2[] = { '(', '?', '>', '\x0D', '\x0A', '?',
350 '|', '[', '\x0A', '\x0B', '\x0C', '\x85', ']', ')', '\0' };
351 return e2;
352#ifdef NDNBOOST_MSVC
353# pragma warning(pop)
354#endif
355}
356
357} // re_detail
358} // boost
359
360#ifdef NDNBOOST_MSVC
361#pragma warning(push)
362#pragma warning(disable: 4103)
363#endif
364#ifdef NDNBOOST_HAS_ABI_HEADERS
365# include NDNBOOST_ABI_SUFFIX
366#endif
367#ifdef NDNBOOST_MSVC
368#pragma warning(pop)
369#endif
370
371#endif