1 | /* |
2 | * |
3 | * Copyright (c) 1998-2005 |
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_workarounds.cpp |
15 | * VERSION see <boost/version.hpp> |
16 | * DESCRIPTION: Declares Misc workarounds. |
17 | */ |
18 | |
19 | #ifndef BOOST_REGEX_WORKAROUND_HPP |
20 | #define BOOST_REGEX_WORKAROUND_HPP |
21 | |
22 | |
23 | #include <new> |
24 | #include <cstring> |
25 | #include <cstdlib> |
26 | #include <cstddef> |
27 | #include <cassert> |
28 | #include <cstdio> |
29 | #include <climits> |
30 | #include <string> |
31 | #include <stdexcept> |
32 | #include <iterator> |
33 | #include <algorithm> |
34 | #include <iosfwd> |
35 | #include <vector> |
36 | #include <set> |
37 | #include <map> |
38 | #include <boost/limits.hpp> |
39 | #include <boost/assert.hpp> |
40 | #include <boost/cstdint.hpp> |
41 | #include <boost/throw_exception.hpp> |
42 | #include <boost/scoped_ptr.hpp> |
43 | #include <boost/scoped_array.hpp> |
44 | #include <boost/shared_ptr.hpp> |
45 | #include <boost/mpl/bool_fwd.hpp> |
46 | #include <boost/regex/config.hpp> |
47 | #ifndef BOOST_NO_STD_LOCALE |
48 | # include <locale> |
49 | #endif |
50 | |
51 | #if defined(BOOST_NO_STDC_NAMESPACE) |
52 | namespace std{ |
53 | using ::sprintf; using ::strcpy; using ::strcat; using ::strlen; |
54 | } |
55 | #endif |
56 | |
57 | namespace boost{ namespace BOOST_REGEX_DETAIL_NS{ |
58 | #ifdef BOOST_NO_STD_DISTANCE |
59 | template <class T> |
60 | std::ptrdiff_t distance(const T& x, const T& y) |
61 | { return y - x; } |
62 | #else |
63 | using std::distance; |
64 | #endif |
65 | }} |
66 | |
67 | |
68 | #ifdef BOOST_REGEX_NO_BOOL |
69 | # define BOOST_REGEX_MAKE_BOOL(x) static_cast<bool>((x) ? true : false) |
70 | #else |
71 | # define BOOST_REGEX_MAKE_BOOL(x) static_cast<bool>(x) |
72 | #endif |
73 | |
74 | /***************************************************************************** |
75 | * |
76 | * Fix broken namespace support: |
77 | * |
78 | ****************************************************************************/ |
79 | |
80 | #if defined(BOOST_NO_STDC_NAMESPACE) && defined(__cplusplus) |
81 | |
82 | namespace std{ |
83 | using ::ptrdiff_t; |
84 | using ::size_t; |
85 | using ::abs; |
86 | using ::memset; |
87 | using ::memcpy; |
88 | } |
89 | |
90 | #endif |
91 | |
92 | /***************************************************************************** |
93 | * |
94 | * helper functions pointer_construct/pointer_destroy: |
95 | * |
96 | ****************************************************************************/ |
97 | |
98 | #ifdef __cplusplus |
99 | namespace boost{ namespace BOOST_REGEX_DETAIL_NS{ |
100 | |
101 | #ifdef BOOST_MSVC |
102 | #pragma warning (push) |
103 | #pragma warning (disable : 4100) |
104 | #endif |
105 | |
106 | template <class T> |
107 | inline void pointer_destroy(T* p) |
108 | { p->~T(); (void)p; } |
109 | |
110 | #ifdef BOOST_MSVC |
111 | #pragma warning (pop) |
112 | #endif |
113 | |
114 | template <class T> |
115 | inline void pointer_construct(T* p, const T& t) |
116 | { new (p) T(t); } |
117 | |
118 | }} // namespaces |
119 | #endif |
120 | |
121 | /***************************************************************************** |
122 | * |
123 | * helper function copy: |
124 | * |
125 | ****************************************************************************/ |
126 | |
127 | #ifdef __cplusplus |
128 | namespace boost{ namespace BOOST_REGEX_DETAIL_NS{ |
129 | #if BOOST_WORKAROUND(BOOST_MSVC,>=1400) && BOOST_WORKAROUND(BOOST_MSVC, <1600) && defined(_CPPLIB_VER) && defined(BOOST_DINKUMWARE_STDLIB) && !(defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) |
130 | // |
131 | // MSVC 8 will either emit warnings or else refuse to compile |
132 | // code that makes perfectly legitimate use of std::copy, when |
133 | // the OutputIterator type is a user-defined class (apparently all user |
134 | // defined iterators are "unsafe"). This code works around that: |
135 | // |
136 | template<class InputIterator, class OutputIterator> |
137 | inline OutputIterator copy( |
138 | InputIterator first, |
139 | InputIterator last, |
140 | OutputIterator dest |
141 | ) |
142 | { |
143 | return stdext::unchecked_copy(first, last, dest); |
144 | } |
145 | template<class InputIterator1, class InputIterator2> |
146 | inline bool equal( |
147 | InputIterator1 first, |
148 | InputIterator1 last, |
149 | InputIterator2 with |
150 | ) |
151 | { |
152 | return stdext::unchecked_equal(first, last, with); |
153 | } |
154 | #elif BOOST_WORKAROUND(BOOST_MSVC, > 1500) |
155 | // |
156 | // MSVC 10 will either emit warnings or else refuse to compile |
157 | // code that makes perfectly legitimate use of std::copy, when |
158 | // the OutputIterator type is a user-defined class (apparently all user |
159 | // defined iterators are "unsafe"). What's more Microsoft have removed their |
160 | // non-standard "unchecked" versions, even though their still in the MS |
161 | // documentation!! Work around this as best we can: |
162 | // |
163 | template<class InputIterator, class OutputIterator> |
164 | inline OutputIterator copy( |
165 | InputIterator first, |
166 | InputIterator last, |
167 | OutputIterator dest |
168 | ) |
169 | { |
170 | while(first != last) |
171 | *dest++ = *first++; |
172 | return dest; |
173 | } |
174 | template<class InputIterator1, class InputIterator2> |
175 | inline bool equal( |
176 | InputIterator1 first, |
177 | InputIterator1 last, |
178 | InputIterator2 with |
179 | ) |
180 | { |
181 | while(first != last) |
182 | if(*first++ != *with++) return false; |
183 | return true; |
184 | } |
185 | #else |
186 | using std::copy; |
187 | using std::equal; |
188 | #endif |
189 | #if BOOST_WORKAROUND(BOOST_MSVC,>=1400) && defined(__STDC_WANT_SECURE_LIB__) && __STDC_WANT_SECURE_LIB__ |
190 | |
191 | // use safe versions of strcpy etc: |
192 | using ::strcpy_s; |
193 | using ::strcat_s; |
194 | #else |
195 | inline std::size_t strcpy_s( |
196 | char *strDestination, |
197 | std::size_t sizeInBytes, |
198 | const char *strSource |
199 | ) |
200 | { |
201 | if(std::strlen(strSource)+1 > sizeInBytes) |
202 | return 1; |
203 | std::strcpy(strDestination, strSource); |
204 | return 0; |
205 | } |
206 | inline std::size_t strcat_s( |
207 | char *strDestination, |
208 | std::size_t sizeInBytes, |
209 | const char *strSource |
210 | ) |
211 | { |
212 | if(std::strlen(strSource) + std::strlen(strDestination) + 1 > sizeInBytes) |
213 | return 1; |
214 | std::strcat(strDestination, strSource); |
215 | return 0; |
216 | } |
217 | |
218 | #endif |
219 | |
220 | inline void overflow_error_if_not_zero(std::size_t i) |
221 | { |
222 | if(i) |
223 | { |
224 | std::overflow_error e("String buffer too small" ); |
225 | boost::throw_exception(e); |
226 | } |
227 | } |
228 | |
229 | }} // namespaces |
230 | |
231 | #endif // __cplusplus |
232 | |
233 | #endif // include guard |
234 | |
235 | |