96.00% Lines (24/25) 100.00% Functions (4/4)
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_CI_STRING_HPP 11   #ifndef BOOST_URL_GRAMMAR_DETAIL_CI_STRING_HPP
12   #define BOOST_URL_GRAMMAR_DETAIL_CI_STRING_HPP 12   #define BOOST_URL_GRAMMAR_DETAIL_CI_STRING_HPP
13   13  
14   #include <boost/core/detail/string_view.hpp> 14   #include <boost/core/detail/string_view.hpp>
15   #include <boost/assert.hpp> 15   #include <boost/assert.hpp>
16   #include <cstdint> 16   #include <cstdint>
17   #include <iterator> 17   #include <iterator>
18   #include <type_traits> 18   #include <type_traits>
19   19  
20   namespace boost { 20   namespace boost {
21   namespace urls { 21   namespace urls {
22   namespace grammar { 22   namespace grammar {
23   namespace detail { 23   namespace detail {
24   24  
25   template<class T, class = void> 25   template<class T, class = void>
26   struct is_char_iter : std::false_type {}; 26   struct is_char_iter : std::false_type {};
27   27  
28   template<class T> 28   template<class T>
29   struct is_char_iter<T, void_t< 29   struct is_char_iter<T, void_t<
30   decltype(std::declval<char&>() = 30   decltype(std::declval<char&>() =
31   *std::declval<T const&>()), 31   *std::declval<T const&>()),
32   decltype(std::declval<T&>() = 32   decltype(std::declval<T&>() =
33   ++std::declval<T&>()), 33   ++std::declval<T&>()),
34   decltype(std::declval<bool&>() = 34   decltype(std::declval<bool&>() =
35   std::declval<T const&>() == 35   std::declval<T const&>() ==
36   std::declval<T const&>()) 36   std::declval<T const&>())
37   > > : std::integral_constant<bool, 37   > > : std::integral_constant<bool,
38   std::is_copy_constructible<T>::value> 38   std::is_copy_constructible<T>::value>
39   { 39   {
40   }; 40   };
41   41  
42   template<class T, class = void> 42   template<class T, class = void>
43   struct is_char_range : std::false_type {}; 43   struct is_char_range : std::false_type {};
44   44  
45   template<class T> 45   template<class T>
46   struct is_char_range<T, void_t< 46   struct is_char_range<T, void_t<
47   decltype(std::declval<T const&>().begin()), 47   decltype(std::declval<T const&>().begin()),
48   decltype(std::declval<T const&>().end()) 48   decltype(std::declval<T const&>().end())
49   > > : std::integral_constant<bool, 49   > > : std::integral_constant<bool,
50   is_char_iter<decltype( 50   is_char_iter<decltype(
51   std::declval<T const&>( 51   std::declval<T const&>(
52   ).begin())>::value && 52   ).begin())>::value &&
53   is_char_iter<decltype( 53   is_char_iter<decltype(
54   std::declval<T const&>( 54   std::declval<T const&>(
55   ).end())>::value> 55   ).end())>::value>
56   { 56   {
57   }; 57   };
58   58  
59   template<class T> 59   template<class T>
60   struct type_id_impl 60   struct type_id_impl
61   { 61   {
62   static 62   static
63   constexpr 63   constexpr
64   char cid = 0; 64   char cid = 0;
65   }; 65   };
66   66  
67   template<class T> 67   template<class T>
68   constexpr 68   constexpr
69   char 69   char
70   type_id_impl<T>::cid; 70   type_id_impl<T>::cid;
71   71  
72   template<class T> 72   template<class T>
73   constexpr 73   constexpr
74   std::uintptr_t 74   std::uintptr_t
HITCBC 75   762 type_id() noexcept 75   762 type_id() noexcept
76   { 76   {
77   return std::uintptr_t( 77   return std::uintptr_t(
HITCBC 78   762 &type_id_impl<T>::cid); 78   762 &type_id_impl<T>::cid);
79   } 79   }
80   80  
81   //------------------------------------------------ 81   //------------------------------------------------
82   82  
83   constexpr 83   constexpr
84   char 84   char
HITCBC 85   77779 to_lower(char c) noexcept 85   77779 to_lower(char c) noexcept
86   { 86   {
87   return 87   return
HITCBC 88   76156 (c >= 'A' && 88   76156 (c >= 'A' &&
89   c <= 'Z') 89   c <= 'Z')
HITCBC 90   2396 ? c + 'a' - 'A' 90   2396 ? c + 'a' - 'A'
HITCBC 91   153935 : c; 91   153935 : c;
92   } 92   }
93   93  
94   constexpr 94   constexpr
95   char 95   char
HITCBC 96   387 to_upper(char c) noexcept 96   387 to_upper(char c) noexcept
97   { 97   {
98   return 98   return
HITCBC 99   86 (c >= 'a' && 99   86 (c >= 'a' &&
100   c <= 'z') 100   c <= 'z')
HITCBC 101   86 ? c - ('a' - 'A') 101   86 ? c - ('a' - 'A')
HITCBC 102   473 : c; 102   473 : c;
103   } 103   }
104   104  
105   //------------------------------------------------ 105   //------------------------------------------------
106   106  
107   template<class S0, class S1> 107   template<class S0, class S1>
108   auto 108   auto
HITCBC 109   254 ci_is_equal( 109   254 ci_is_equal(
110   S0 const& s0, 110   S0 const& s0,
111   S1 const& s1) -> 111   S1 const& s1) ->
112   typename std::enable_if< 112   typename std::enable_if<
113   ! std::is_convertible< 113   ! std::is_convertible<
114   S0, core::string_view>::value || 114   S0, core::string_view>::value ||
115   ! std::is_convertible< 115   ! std::is_convertible<
116   S1, core::string_view>::value, 116   S1, core::string_view>::value,
117   bool>::type 117   bool>::type
118   { 118   {
119   /* If you get a compile error here, it 119   /* If you get a compile error here, it
120   means that a range you passed does 120   means that a range you passed does
121   not meet the requirements stated 121   not meet the requirements stated
122   in the documentation. 122   in the documentation.
123   */ 123   */
124   static_assert( 124   static_assert(
125   is_char_range<S0>::value, 125   is_char_range<S0>::value,
126   "Type requirements not met"); 126   "Type requirements not met");
127   static_assert( 127   static_assert(
128   is_char_range<S1>::value, 128   is_char_range<S1>::value,
129   "Type requirements not met"); 129   "Type requirements not met");
130   130  
131   // Arguments are sorted by type to 131   // Arguments are sorted by type to
132   // reduce the number of function 132   // reduce the number of function
133   // template instantiations. This 133   // template instantiations. This
134   // works because: 134   // works because:
135   // 135   //
136   // ci_is_equal(s0,s1) == ci_is_equal(s1,s0) 136   // ci_is_equal(s0,s1) == ci_is_equal(s1,s0)
137   // 137   //
HITCBC 138   127 BOOST_ASSERT( 138   127 BOOST_ASSERT(
139   detail::type_id<S0>() <= 139   detail::type_id<S0>() <=
140   detail::type_id<S1>()); 140   detail::type_id<S1>());
141   141  
HITCBC 142   254 auto it0 = s0.begin(); 142   254 auto it0 = s0.begin();
HITCBC 143   254 auto it1 = s1.begin(); 143   254 auto it1 = s1.begin();
HITCBC 144   254 auto const end0 = s0.end(); 144   254 auto const end0 = s0.end();
HITCBC 145   254 auto const end1 = s1.end(); 145   254 auto const end1 = s1.end();
146   for(;;) 146   for(;;)
147   { 147   {
HITCBC 148   364 if(it0 == end0) 148   364 if(it0 == end0)
HITCBC 149   66 return it1 == end1; 149   66 return it1 == end1;
HITCBC 150   298 if(it1 == end1) 150   298 if(it1 == end1)
MISUBC 151   return false; 151   return false;
HITCBC 152   596 if( to_lower(*it0) != 152   596 if( to_lower(*it0) !=
HITCBC 153   298 to_lower(*it1)) 153   298 to_lower(*it1))
HITCBC 154   188 return false; 154   188 return false;
HITCBC 155   110 ++it0; 155   110 ++it0;
HITCBC 156   110 ++it1; 156   110 ++it1;
157   } 157   }
158   } 158   }
159   159  
160   //------------------------------------------------ 160   //------------------------------------------------
161   161  
162   BOOST_URL_DECL 162   BOOST_URL_DECL
163   bool 163   bool
164   ci_is_equal( 164   ci_is_equal(
165   core::string_view s0, 165   core::string_view s0,
166   core::string_view s1) noexcept; 166   core::string_view s1) noexcept;
167   167  
168   BOOST_URL_DECL 168   BOOST_URL_DECL
169   bool 169   bool
170   ci_is_less( 170   ci_is_less(
171   core::string_view s0, 171   core::string_view s0,
172   core::string_view s1) noexcept; 172   core::string_view s1) noexcept;
173   173  
174   } // detail 174   } // detail
175   } // grammar 175   } // grammar
176   } // urls 176   } // urls
177   } // boost 177   } // boost
178   178  
179   #endif 179   #endif