Line data Source code
1 : //
2 : // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
3 : //
4 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 : //
7 : // Official repository: https://github.com/boostorg/url
8 : //
9 :
10 : #ifndef BOOST_URL_GRAMMAR_DETAIL_CHARSET_HPP
11 : #define BOOST_URL_GRAMMAR_DETAIL_CHARSET_HPP
12 :
13 : #include <boost/core/bit.hpp>
14 : #include <type_traits>
15 :
16 : #ifdef BOOST_URL_USE_SSE2
17 : # include <emmintrin.h>
18 : # include <xmmintrin.h>
19 : # ifdef _MSC_VER
20 : # include <intrin.h>
21 : # endif
22 : #endif
23 :
24 : #ifdef _MSC_VER
25 : #pragma warning(push)
26 : #pragma warning(disable: 4127) // conditional expression is constant
27 : #endif
28 :
29 : namespace boost {
30 : namespace urls {
31 : namespace grammar {
32 : namespace detail {
33 :
34 : template<class T, class = void>
35 : struct has_find_if : std::false_type {};
36 :
37 : template<class T>
38 : struct has_find_if<T, void_t<
39 : decltype(
40 : std::declval<char const*&>() =
41 : std::declval<T const&>().find_if(
42 : std::declval<char const*>(),
43 : std::declval<char const*>())
44 : )>> : std::true_type
45 : {
46 : };
47 :
48 : template<class T, class = void>
49 : struct has_find_if_not : std::false_type {};
50 :
51 : template<class T>
52 : struct has_find_if_not<T, void_t<
53 : decltype(
54 : std::declval<char const*&>() =
55 : std::declval<T const&>().find_if_not(
56 : std::declval<char const*>(),
57 : std::declval<char const*>())
58 : )>> : std::true_type
59 : {
60 : };
61 :
62 : template<class Pred>
63 : char const*
64 1 : find_if(
65 : char const* first,
66 : char const* const last,
67 : Pred const& pred,
68 : std::false_type) noexcept
69 : {
70 9 : while(first != last)
71 : {
72 9 : if(pred(*first))
73 1 : break;
74 8 : ++first;
75 : }
76 1 : return first;
77 : }
78 :
79 : template<class Pred>
80 : char const*
81 2883 : find_if(
82 : char const* first,
83 : char const* const last,
84 : Pred const& pred,
85 : std::true_type) noexcept
86 : {
87 2883 : return pred.find_if(
88 2883 : first, last);
89 : }
90 :
91 : template<class Pred>
92 : char const*
93 1 : find_if_not(
94 : char const* first,
95 : char const* const last,
96 : Pred const& pred,
97 : std::false_type) noexcept
98 : {
99 4 : while(first != last)
100 : {
101 4 : if(! pred(*first))
102 1 : break;
103 3 : ++first;
104 : }
105 1 : return first;
106 : }
107 :
108 : template<class Pred>
109 : char const*
110 17723 : find_if_not(
111 : char const* first,
112 : char const* const last,
113 : Pred const& pred,
114 : std::true_type) noexcept
115 : {
116 17723 : return pred.find_if_not(
117 17723 : first, last);
118 : }
119 :
120 : #ifdef BOOST_URL_USE_SSE2
121 :
122 : // by Peter Dimov
123 : template<class Pred>
124 : char const*
125 2627 : find_if_pred(
126 : Pred const& pred,
127 : char const* first,
128 : char const* last ) noexcept
129 : {
130 2936 : while( last - first >= 16 )
131 : {
132 642 : unsigned char r[ 16 ] = {};
133 10914 : for( int i = 0; i < 16; ++i )
134 10272 : r[ i ] = pred( first[ i ] )? 0xFF: 0x00;
135 642 : __m128i r2 = _mm_loadu_si128( (__m128i const*)r );
136 642 : unsigned r3 = _mm_movemask_epi8( r2 );
137 642 : if( r3 )
138 333 : return first + boost::core::countr_zero( r3 );
139 309 : first += 16;
140 : }
141 2294 : while(
142 8452 : first != last &&
143 3323 : ! pred(*first))
144 : {
145 2835 : ++first;
146 : }
147 2294 : return first;
148 : }
149 :
150 : // by Peter Dimov
151 : template<class Pred>
152 : char const*
153 15083 : find_if_not_pred(
154 : Pred const& pred,
155 : char const* first,
156 : char const* last ) noexcept
157 : {
158 15472 : while( last - first >= 16 )
159 : {
160 3753 : unsigned char r[ 16 ] = {};
161 63801 : for( int i = 0; i < 16; ++i )
162 60048 : r[ i ] = pred( first[ i ] )? 0x00: 0xFF;
163 3753 : __m128i r2 = _mm_loadu_si128( (__m128i const*)r );
164 3753 : unsigned r3 = _mm_movemask_epi8( r2 );
165 3753 : if( r3 )
166 3364 : return first + boost::core::countr_zero( r3 );
167 389 : first += 16;
168 : }
169 11719 : while(
170 78185 : first != last &&
171 37402 : pred(*first))
172 : {
173 29064 : ++first;
174 : }
175 11719 : return first;
176 : }
177 :
178 : #endif
179 :
180 : } // detail
181 : } // grammar
182 : } // urls
183 : } // boost
184 :
185 : #ifdef _MSC_VER
186 : #pragma warning(pop)
187 : #endif
188 :
189 : #endif
|