File indexing completed on 2025-01-18 09:53:27
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_URL_GRAMMAR_DETAIL_CHARSET_HPP
0011 #define BOOST_URL_GRAMMAR_DETAIL_CHARSET_HPP
0012
0013 #include <boost/core/bit.hpp>
0014 #include <type_traits>
0015
0016 #ifdef BOOST_URL_USE_SSE2
0017 # include <emmintrin.h>
0018 # include <xmmintrin.h>
0019 # ifdef _MSC_VER
0020 # include <intrin.h>
0021 # endif
0022 #endif
0023
0024 #ifdef _MSC_VER
0025 #pragma warning(push)
0026 #pragma warning(disable: 4127)
0027 #endif
0028
0029 namespace boost {
0030 namespace urls {
0031 namespace grammar {
0032 namespace detail {
0033
0034 template<class T, class = void>
0035 struct has_find_if : std::false_type {};
0036
0037 template<class T>
0038 struct has_find_if<T, void_t<
0039 decltype(
0040 std::declval<char const*&>() =
0041 std::declval<T const&>().find_if(
0042 std::declval<char const*>(),
0043 std::declval<char const*>())
0044 )>> : std::true_type
0045 {
0046 };
0047
0048 template<class T, class = void>
0049 struct has_find_if_not : std::false_type {};
0050
0051 template<class T>
0052 struct has_find_if_not<T, void_t<
0053 decltype(
0054 std::declval<char const*&>() =
0055 std::declval<T const&>().find_if_not(
0056 std::declval<char const*>(),
0057 std::declval<char const*>())
0058 )>> : std::true_type
0059 {
0060 };
0061
0062 template<class Pred>
0063 char const*
0064 find_if(
0065 char const* first,
0066 char const* const last,
0067 Pred const& pred,
0068 std::false_type) noexcept
0069 {
0070 while(first != last)
0071 {
0072 if(pred(*first))
0073 break;
0074 ++first;
0075 }
0076 return first;
0077 }
0078
0079 template<class Pred>
0080 char const*
0081 find_if(
0082 char const* first,
0083 char const* const last,
0084 Pred const& pred,
0085 std::true_type) noexcept
0086 {
0087 return pred.find_if(
0088 first, last);
0089 }
0090
0091 template<class Pred>
0092 char const*
0093 find_if_not(
0094 char const* first,
0095 char const* const last,
0096 Pred const& pred,
0097 std::false_type) noexcept
0098 {
0099 while(first != last)
0100 {
0101 if(! pred(*first))
0102 break;
0103 ++first;
0104 }
0105 return first;
0106 }
0107
0108 template<class Pred>
0109 char const*
0110 find_if_not(
0111 char const* first,
0112 char const* const last,
0113 Pred const& pred,
0114 std::true_type) noexcept
0115 {
0116 return pred.find_if_not(
0117 first, last);
0118 }
0119
0120 #ifdef BOOST_URL_USE_SSE2
0121
0122
0123 template<class Pred>
0124 char const*
0125 find_if_pred(
0126 Pred const& pred,
0127 char const* first,
0128 char const* last ) noexcept
0129 {
0130 while( last - first >= 16 )
0131 {
0132 unsigned char r[ 16 ] = {};
0133 for( int i = 0; i < 16; ++i )
0134 r[ i ] = pred( first[ i ] )? 0xFF: 0x00;
0135 __m128i r2 = _mm_loadu_si128( (__m128i const*)r );
0136 unsigned r3 = _mm_movemask_epi8( r2 );
0137 if( r3 )
0138 return first + boost::core::countr_zero( r3 );
0139 first += 16;
0140 }
0141 while(
0142 first != last &&
0143 ! pred(*first))
0144 {
0145 ++first;
0146 }
0147 return first;
0148 }
0149
0150
0151 template<class Pred>
0152 char const*
0153 find_if_not_pred(
0154 Pred const& pred,
0155 char const* first,
0156 char const* last ) noexcept
0157 {
0158 while( last - first >= 16 )
0159 {
0160 unsigned char r[ 16 ] = {};
0161 for( int i = 0; i < 16; ++i )
0162 r[ i ] = pred( first[ i ] )? 0x00: 0xFF;
0163 __m128i r2 = _mm_loadu_si128( (__m128i const*)r );
0164 unsigned r3 = _mm_movemask_epi8( r2 );
0165 if( r3 )
0166 return first + boost::core::countr_zero( r3 );
0167 first += 16;
0168 }
0169 while(
0170 first != last &&
0171 pred(*first))
0172 {
0173 ++first;
0174 }
0175 return first;
0176 }
0177
0178 #endif
0179
0180 }
0181 }
0182 }
0183 }
0184
0185 #ifdef _MSC_VER
0186 #pragma warning(pop)
0187 #endif
0188
0189 #endif