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 9 : 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 : return pred.find_if( 88 2883 : first, last); 89 : } 90 : 91 : template<class Pred> 92 : char const* 93 4 : 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 17683 : find_if_not( 111 : char const* first, 112 : char const* const last, 113 : Pred const& pred, 114 : std::true_type) noexcept 115 : { 116 : return pred.find_if_not( 117 17683 : first, last); 118 : } 119 : 120 : #ifdef BOOST_URL_USE_SSE2 121 : 122 : // by Peter Dimov 123 : template<class Pred> 124 : char const* 125 2936 : 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 2835 : 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 15440 : find_if_not_pred( 154 : Pred const& pred, 155 : char const* first, 156 : char const* last ) noexcept 157 : { 158 15440 : while( last - first >= 16 ) 159 : { 160 3735 : unsigned char r[ 16 ] = {}; 161 63495 : for( int i = 0; i < 16; ++i ) 162 59760 : r[ i ] = pred( first[ i ] )? 0x00: 0xFF; 163 3735 : __m128i r2 = _mm_loadu_si128( (__m128i const*)r ); 164 3735 : unsigned r3 = _mm_movemask_epi8( r2 ); 165 3735 : if( r3 ) 166 3346 : return first + boost::core::countr_zero( r3 ); 167 389 : first += 16; 168 : } 169 28970 : while( 170 77978 : first != last && 171 37303 : pred(*first)) 172 : { 173 28970 : ++first; 174 : } 175 11705 : 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