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  
//
4  
//
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5  
// 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  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
//
7  
//
7  
// Official repository: https://github.com/boostorg/url
8  
// Official repository: https://github.com/boostorg/url
8  
//
9  
//
9  

10  

10  
#ifndef BOOST_URL_GRAMMAR_DETAIL_CHARSET_HPP
11  
#ifndef BOOST_URL_GRAMMAR_DETAIL_CHARSET_HPP
11  
#define BOOST_URL_GRAMMAR_DETAIL_CHARSET_HPP
12  
#define BOOST_URL_GRAMMAR_DETAIL_CHARSET_HPP
12  

13  

 
14 +
#include <boost/url/detail/config.hpp>
13  
#include <boost/core/bit.hpp>
15  
#include <boost/core/bit.hpp>
14  
#include <type_traits>
16  
#include <type_traits>
15  

17  

16  
#ifdef BOOST_URL_USE_SSE2
18  
#ifdef BOOST_URL_USE_SSE2
17  
# include <emmintrin.h>
19  
# include <emmintrin.h>
18  
# include <xmmintrin.h>
20  
# include <xmmintrin.h>
19  
# ifdef _MSC_VER
21  
# ifdef _MSC_VER
20  
#  include <intrin.h>
22  
#  include <intrin.h>
21  
# endif
23  
# endif
22  
#endif
24  
#endif
23  

25  

24  
#ifdef _MSC_VER
26  
#ifdef _MSC_VER
25  
#pragma warning(push)
27  
#pragma warning(push)
26  
#pragma warning(disable: 4127) // conditional expression is constant
28  
#pragma warning(disable: 4127) // conditional expression is constant
27  
#endif
29  
#endif
28  

30  

29  
namespace boost {
31  
namespace boost {
30  
namespace urls {
32  
namespace urls {
31  
namespace grammar {
33  
namespace grammar {
32  
namespace detail {
34  
namespace detail {
33  

35  

34  
template<class T, class = void>
36  
template<class T, class = void>
35  
struct has_find_if : std::false_type {};
37  
struct has_find_if : std::false_type {};
36  

38  

37  
template<class T>
39  
template<class T>
38  
struct has_find_if<T, void_t<
40  
struct has_find_if<T, void_t<
39  
    decltype(
41  
    decltype(
40  
    std::declval<char const*&>() =
42  
    std::declval<char const*&>() =
41  
        std::declval<T const&>().find_if(
43  
        std::declval<T const&>().find_if(
42  
            std::declval<char const*>(),
44  
            std::declval<char const*>(),
43  
            std::declval<char const*>())
45  
            std::declval<char const*>())
44  
            )>> : std::true_type
46  
            )>> : std::true_type
45  
{
47  
{
46  
};
48  
};
47  

49  

48  
template<class T, class = void>
50  
template<class T, class = void>
49  
struct has_find_if_not : std::false_type {};
51  
struct has_find_if_not : std::false_type {};
50  

52  

51  
template<class T>
53  
template<class T>
52  
struct has_find_if_not<T, void_t<
54  
struct has_find_if_not<T, void_t<
53  
    decltype(
55  
    decltype(
54  
    std::declval<char const*&>() =
56  
    std::declval<char const*&>() =
55  
        std::declval<T const&>().find_if_not(
57  
        std::declval<T const&>().find_if_not(
56  
            std::declval<char const*>(),
58  
            std::declval<char const*>(),
57  
            std::declval<char const*>())
59  
            std::declval<char const*>())
58  
            )>> : std::true_type
60  
            )>> : std::true_type
59  
{
61  
{
60  
};
62  
};
61  

63  

62  
template<class Pred>
64  
template<class Pred>
 
65 +
BOOST_URL_CXX14_CONSTEXPR
63  
char const*
66  
char const*
64  
find_if(
67  
find_if(
65  
    char const* first,
68  
    char const* first,
66  
    char const* const last,
69  
    char const* const last,
67  
    Pred const& pred,
70  
    Pred const& pred,
68  
    std::false_type) noexcept
71  
    std::false_type) noexcept
69  
{
72  
{
70  
    while(first != last)
73  
    while(first != last)
71  
    {
74  
    {
72  
        if(pred(*first))
75  
        if(pred(*first))
73  
            break;
76  
            break;
74  
        ++first;
77  
        ++first;
75  
    }
78  
    }
76  
    return first;
79  
    return first;
77  
}
80  
}
78  

81  

79  
template<class Pred>
82  
template<class Pred>
 
83 +
BOOST_URL_CXX14_CONSTEXPR
80  
char const*
84  
char const*
81  
find_if(
85  
find_if(
82  
    char const* first,
86  
    char const* first,
83  
    char const* const last,
87  
    char const* const last,
84  
    Pred const& pred,
88  
    Pred const& pred,
85  
    std::true_type) noexcept
89  
    std::true_type) noexcept
86  
{
90  
{
 
91 +
#if (__cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
 
92 +
    if (__builtin_is_constant_evaluated())
 
93 +
        return find_if(first, last, pred,
 
94 +
            std::false_type{});
 
95 +
#endif
87  
    return pred.find_if(
96  
    return pred.find_if(
88  
        first, last);
97  
        first, last);
89  
}
98  
}
90  

99  

91  
template<class Pred>
100  
template<class Pred>
 
101 +
BOOST_URL_CXX14_CONSTEXPR
92  
char const*
102  
char const*
93  
find_if_not(
103  
find_if_not(
94  
    char const* first,
104  
    char const* first,
95  
    char const* const last,
105  
    char const* const last,
96  
    Pred const& pred,
106  
    Pred const& pred,
97  
    std::false_type) noexcept
107  
    std::false_type) noexcept
98  
{
108  
{
99  
    while(first != last)
109  
    while(first != last)
100  
    {
110  
    {
101  
        if(! pred(*first))
111  
        if(! pred(*first))
102  
            break;
112  
            break;
103  
        ++first;
113  
        ++first;
104  
    }
114  
    }
105  
    return first;
115  
    return first;
106  
}
116  
}
107  

117  

108  
template<class Pred>
118  
template<class Pred>
 
119 +
BOOST_URL_CXX14_CONSTEXPR
109  
char const*
120  
char const*
110  
find_if_not(
121  
find_if_not(
111  
    char const* first,
122  
    char const* first,
112  
    char const* const last,
123  
    char const* const last,
113  
    Pred const& pred,
124  
    Pred const& pred,
114  
    std::true_type) noexcept
125  
    std::true_type) noexcept
115  
{
126  
{
 
127 +
#if (__cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
 
128 +
    if (__builtin_is_constant_evaluated())
 
129 +
        return find_if_not(first, last, pred,
 
130 +
            std::false_type{});
 
131 +
#endif
116  
    return pred.find_if_not(
132  
    return pred.find_if_not(
117  
        first, last);
133  
        first, last);
118  
}
134  
}
119  

135  

120  
#ifdef BOOST_URL_USE_SSE2
136  
#ifdef BOOST_URL_USE_SSE2
121  

137  

122  
// by Peter Dimov
138  
// by Peter Dimov
123  
template<class Pred>
139  
template<class Pred>
124  
char const*
140  
char const*
125  
find_if_pred(
141  
find_if_pred(
126  
    Pred const& pred,
142  
    Pred const& pred,
127  
    char const* first,
143  
    char const* first,
128  
    char const* last ) noexcept
144  
    char const* last ) noexcept
129  
{
145  
{
130  
    while( last - first >= 16 )
146  
    while( last - first >= 16 )
131  
    {
147  
    {
132  
        unsigned char r[ 16 ] = {};
148  
        unsigned char r[ 16 ] = {};
133  
        for( int i = 0; i < 16; ++i )
149  
        for( int i = 0; i < 16; ++i )
134  
            r[ i ] = pred( first[ i ] )? 0xFF: 0x00;
150  
            r[ i ] = pred( first[ i ] )? 0xFF: 0x00;
135  
        __m128i r2 = _mm_loadu_si128( (__m128i const*)r );
151  
        __m128i r2 = _mm_loadu_si128( (__m128i const*)r );
136  
        unsigned r3 = _mm_movemask_epi8( r2 );
152  
        unsigned r3 = _mm_movemask_epi8( r2 );
137  
        if( r3 )
153  
        if( r3 )
138  
            return first + boost::core::countr_zero( r3 );
154  
            return first + boost::core::countr_zero( r3 );
139  
        first += 16;
155  
        first += 16;
140  
    }
156  
    }
141  
    while(
157  
    while(
142  
        first != last &&
158  
        first != last &&
143  
        ! pred(*first))
159  
        ! pred(*first))
144  
    {
160  
    {
145  
        ++first;
161  
        ++first;
146  
    }
162  
    }
147  
    return first;
163  
    return first;
148  
}
164  
}
149  

165  

150  
// by Peter Dimov
166  
// by Peter Dimov
151  
template<class Pred>
167  
template<class Pred>
152  
char const*
168  
char const*
153  
find_if_not_pred(
169  
find_if_not_pred(
154  
    Pred const& pred,
170  
    Pred const& pred,
155  
    char const* first,
171  
    char const* first,
156  
    char const* last ) noexcept
172  
    char const* last ) noexcept
157  
{
173  
{
158  
    while( last - first >= 16 )
174  
    while( last - first >= 16 )
159  
    {
175  
    {
160  
        unsigned char r[ 16 ] = {};
176  
        unsigned char r[ 16 ] = {};
161  
        for( int i = 0; i < 16; ++i )
177  
        for( int i = 0; i < 16; ++i )
162  
            r[ i ] = pred( first[ i ] )? 0x00: 0xFF;
178  
            r[ i ] = pred( first[ i ] )? 0x00: 0xFF;
163  
        __m128i r2 = _mm_loadu_si128( (__m128i const*)r );
179  
        __m128i r2 = _mm_loadu_si128( (__m128i const*)r );
164  
        unsigned r3 = _mm_movemask_epi8( r2 );
180  
        unsigned r3 = _mm_movemask_epi8( r2 );
165  
        if( r3 )
181  
        if( r3 )
166  
            return first + boost::core::countr_zero( r3 );
182  
            return first + boost::core::countr_zero( r3 );
167  
        first += 16;
183  
        first += 16;
168  
    }
184  
    }
169  
    while(
185  
    while(
170  
        first != last &&
186  
        first != last &&
171  
        pred(*first))
187  
        pred(*first))
172  
    {
188  
    {
173  
        ++first;
189  
        ++first;
174  
    }
190  
    }
175  
    return first;
191  
    return first;
176  
}
192  
}
177  

193  

178  
#endif
194  
#endif
179  

195  

180  
} // detail
196  
} // detail
181  
} // grammar
197  
} // grammar
182  
} // urls
198  
} // urls
183  
} // boost
199  
} // boost
184  

200  

185  
#ifdef _MSC_VER
201  
#ifdef _MSC_VER
186  
#pragma warning(pop)
202  
#pragma warning(pop)
187  
#endif
203  
#endif
188  

204  

189  
#endif
205  
#endif