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