95.65% Lines (22/23)
100.00% Functions (8/8)
| 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_CI_STRING_HPP | 11 | #ifndef BOOST_URL_GRAMMAR_CI_STRING_HPP | |||||
| 12 | #define BOOST_URL_GRAMMAR_CI_STRING_HPP | 12 | #define BOOST_URL_GRAMMAR_CI_STRING_HPP | |||||
| 13 | 13 | |||||||
| 14 | #include <boost/url/detail/config.hpp> | 14 | #include <boost/url/detail/config.hpp> | |||||
| 15 | #include <boost/core/detail/string_view.hpp> | 15 | #include <boost/core/detail/string_view.hpp> | |||||
| 16 | #include <boost/url/grammar/detail/ci_string.hpp> | 16 | #include <boost/url/grammar/detail/ci_string.hpp> | |||||
| 17 | #include <cstdlib> | 17 | #include <cstdlib> | |||||
| 18 | 18 | |||||||
| 19 | namespace boost { | 19 | namespace boost { | |||||
| 20 | namespace urls { | 20 | namespace urls { | |||||
| 21 | namespace grammar { | 21 | namespace grammar { | |||||
| 22 | 22 | |||||||
| 23 | // Algorithms for interacting with low-ASCII | 23 | // Algorithms for interacting with low-ASCII | |||||
| 24 | // characters and strings, for implementing | 24 | // characters and strings, for implementing | |||||
| 25 | // semantics in RFCs. These routines do not | 25 | // semantics in RFCs. These routines do not | |||||
| 26 | // use std::locale. | 26 | // use std::locale. | |||||
| 27 | 27 | |||||||
| 28 | //------------------------------------------------ | 28 | //------------------------------------------------ | |||||
| 29 | 29 | |||||||
| 30 | /** Return c converted to lowercase | 30 | /** Return c converted to lowercase | |||||
| 31 | 31 | |||||||
| 32 | This function returns the character, | 32 | This function returns the character, | |||||
| 33 | converting it to lowercase if it is | 33 | converting it to lowercase if it is | |||||
| 34 | uppercase. | 34 | uppercase. | |||||
| 35 | The function is defined only for | 35 | The function is defined only for | |||||
| 36 | low-ASCII characters. | 36 | low-ASCII characters. | |||||
| 37 | 37 | |||||||
| 38 | @par Example | 38 | @par Example | |||||
| 39 | @code | 39 | @code | |||||
| 40 | assert( to_lower( 'A' ) == 'a' ); | 40 | assert( to_lower( 'A' ) == 'a' ); | |||||
| 41 | @endcode | 41 | @endcode | |||||
| 42 | 42 | |||||||
| 43 | @par Exception Safety | 43 | @par Exception Safety | |||||
| 44 | Throws nothing. | 44 | Throws nothing. | |||||
| 45 | 45 | |||||||
| 46 | @return The converted character | 46 | @return The converted character | |||||
| 47 | 47 | |||||||
| 48 | @param c The character to convert | 48 | @param c The character to convert | |||||
| 49 | 49 | |||||||
| 50 | @see | 50 | @see | |||||
| 51 | @ref to_upper. | 51 | @ref to_upper. | |||||
| 52 | */ | 52 | */ | |||||
| 53 | constexpr | 53 | constexpr | |||||
| 54 | char | 54 | char | |||||
| HITCBC | 55 | 77127 | to_lower(char c) noexcept | 55 | 77127 | to_lower(char c) noexcept | ||
| 56 | { | 56 | { | |||||
| HITCBC | 57 | 77127 | return detail::to_lower(c); | 57 | 77127 | return detail::to_lower(c); | ||
| 58 | } | 58 | } | |||||
| 59 | 59 | |||||||
| 60 | /** Return c converted to uppercase | 60 | /** Return c converted to uppercase | |||||
| 61 | 61 | |||||||
| 62 | This function returns the character, | 62 | This function returns the character, | |||||
| 63 | converting it to uppercase if it is | 63 | converting it to uppercase if it is | |||||
| 64 | lowercase. | 64 | lowercase. | |||||
| 65 | The function is defined only for | 65 | The function is defined only for | |||||
| 66 | low-ASCII characters. | 66 | low-ASCII characters. | |||||
| 67 | 67 | |||||||
| 68 | @par Example | 68 | @par Example | |||||
| 69 | @code | 69 | @code | |||||
| 70 | assert( to_upper( 'a' ) == 'A' ); | 70 | assert( to_upper( 'a' ) == 'A' ); | |||||
| 71 | @endcode | 71 | @endcode | |||||
| 72 | 72 | |||||||
| 73 | @par Exception Safety | 73 | @par Exception Safety | |||||
| 74 | Throws nothing. | 74 | Throws nothing. | |||||
| 75 | 75 | |||||||
| 76 | @return The converted character | 76 | @return The converted character | |||||
| 77 | 77 | |||||||
| 78 | @param c The character to convert | 78 | @param c The character to convert | |||||
| 79 | 79 | |||||||
| 80 | @see | 80 | @see | |||||
| 81 | @ref to_lower. | 81 | @ref to_lower. | |||||
| 82 | */ | 82 | */ | |||||
| 83 | constexpr | 83 | constexpr | |||||
| 84 | char | 84 | char | |||||
| HITCBC | 85 | 387 | to_upper(char c) noexcept | 85 | 387 | to_upper(char c) noexcept | ||
| 86 | { | 86 | { | |||||
| HITCBC | 87 | 387 | return detail::to_upper(c); | 87 | 387 | return detail::to_upper(c); | ||
| 88 | } | 88 | } | |||||
| 89 | 89 | |||||||
| 90 | //------------------------------------------------ | 90 | //------------------------------------------------ | |||||
| 91 | 91 | |||||||
| 92 | /** Return the case-insensitive comparison of s0 and s1 | 92 | /** Return the case-insensitive comparison of s0 and s1 | |||||
| 93 | 93 | |||||||
| 94 | This returns the lexicographical comparison | 94 | This returns the lexicographical comparison | |||||
| 95 | of two strings, ignoring case. | 95 | of two strings, ignoring case. | |||||
| 96 | The function is defined only for strings | 96 | The function is defined only for strings | |||||
| 97 | containing low-ASCII characters. | 97 | containing low-ASCII characters. | |||||
| 98 | 98 | |||||||
| 99 | @par Example | 99 | @par Example | |||||
| 100 | @code | 100 | @code | |||||
| 101 | assert( ci_compare( "boost", "Boost" ) == 0 ); | 101 | assert( ci_compare( "boost", "Boost" ) == 0 ); | |||||
| 102 | @endcode | 102 | @endcode | |||||
| 103 | 103 | |||||||
| 104 | @par Exception Safety | 104 | @par Exception Safety | |||||
| 105 | Throws nothing. | 105 | Throws nothing. | |||||
| 106 | 106 | |||||||
| 107 | @return 0 if the strings are equal, -1 if | 107 | @return 0 if the strings are equal, -1 if | |||||
| 108 | `s0` is less than `s1`, or 1 if `s0` is | 108 | `s0` is less than `s1`, or 1 if `s0` is | |||||
| 109 | greater than s1. | 109 | greater than s1. | |||||
| 110 | 110 | |||||||
| 111 | @param s0 The first string | 111 | @param s0 The first string | |||||
| 112 | 112 | |||||||
| 113 | @param s1 The second string | 113 | @param s1 The second string | |||||
| 114 | 114 | |||||||
| 115 | @see | 115 | @see | |||||
| 116 | @ref ci_is_equal, | 116 | @ref ci_is_equal, | |||||
| 117 | @ref ci_is_less. | 117 | @ref ci_is_less. | |||||
| 118 | */ | 118 | */ | |||||
| 119 | BOOST_URL_DECL | 119 | BOOST_URL_DECL | |||||
| 120 | int | 120 | int | |||||
| 121 | ci_compare( | 121 | ci_compare( | |||||
| 122 | core::string_view s0, | 122 | core::string_view s0, | |||||
| 123 | core::string_view s1) noexcept; | 123 | core::string_view s1) noexcept; | |||||
| 124 | 124 | |||||||
| 125 | /** Return the case-insensitive digest of a string | 125 | /** Return the case-insensitive digest of a string | |||||
| 126 | 126 | |||||||
| 127 | The hash function is non-cryptographic and | 127 | The hash function is non-cryptographic and | |||||
| 128 | not hardened against algorithmic complexity | 128 | not hardened against algorithmic complexity | |||||
| 129 | attacks. | 129 | attacks. | |||||
| 130 | Returned digests are suitable for usage in | 130 | Returned digests are suitable for usage in | |||||
| 131 | unordered containers. | 131 | unordered containers. | |||||
| 132 | The function is defined only for strings | 132 | The function is defined only for strings | |||||
| 133 | containing low-ASCII characters. | 133 | containing low-ASCII characters. | |||||
| 134 | 134 | |||||||
| 135 | @return The digest | 135 | @return The digest | |||||
| 136 | 136 | |||||||
| 137 | @param s The string | 137 | @param s The string | |||||
| 138 | */ | 138 | */ | |||||
| 139 | BOOST_URL_DECL | 139 | BOOST_URL_DECL | |||||
| 140 | std::size_t | 140 | std::size_t | |||||
| 141 | ci_digest( | 141 | ci_digest( | |||||
| 142 | core::string_view s) noexcept; | 142 | core::string_view s) noexcept; | |||||
| 143 | 143 | |||||||
| 144 | //------------------------------------------------ | 144 | //------------------------------------------------ | |||||
| 145 | 145 | |||||||
| 146 | /** Return true if s0 equals s1 using case-insensitive comparison | 146 | /** Return true if s0 equals s1 using case-insensitive comparison | |||||
| 147 | 147 | |||||||
| 148 | The function is defined only for strings | 148 | The function is defined only for strings | |||||
| 149 | containing low-ASCII characters. | 149 | containing low-ASCII characters. | |||||
| 150 | 150 | |||||||
| 151 | @param s0 The first string | 151 | @param s0 The first string | |||||
| 152 | @param s1 The second string | 152 | @param s1 The second string | |||||
| 153 | @return `true` if `s0` case-insensitively equals `s1`, otherwise `false` | 153 | @return `true` if `s0` case-insensitively equals `s1`, otherwise `false` | |||||
| 154 | 154 | |||||||
| 155 | @par Example | 155 | @par Example | |||||
| 156 | @code | 156 | @code | |||||
| 157 | assert( ci_is_equal( "Boost", "boost" ) ); | 157 | assert( ci_is_equal( "Boost", "boost" ) ); | |||||
| 158 | @endcode | 158 | @endcode | |||||
| 159 | 159 | |||||||
| 160 | @see | 160 | @see | |||||
| 161 | @ref ci_compare, | 161 | @ref ci_compare, | |||||
| 162 | @ref ci_is_less. | 162 | @ref ci_is_less. | |||||
| 163 | */ | 163 | */ | |||||
| 164 | template< | 164 | template< | |||||
| 165 | class String0, | 165 | class String0, | |||||
| 166 | class String1> | 166 | class String1> | |||||
| 167 | auto | 167 | auto | |||||
| HITCBC | 168 | 254 | ci_is_equal( | 168 | 254 | ci_is_equal( | ||
| 169 | String0 const& s0, | 169 | String0 const& s0, | |||||
| 170 | String1 const& s1) -> | 170 | String1 const& s1) -> | |||||
| 171 | typename std::enable_if< | 171 | typename std::enable_if< | |||||
| 172 | ! std::is_convertible< | 172 | ! std::is_convertible< | |||||
| 173 | String0, core::string_view>::value || | 173 | String0, core::string_view>::value || | |||||
| 174 | ! std::is_convertible< | 174 | ! std::is_convertible< | |||||
| 175 | String1, core::string_view>::value, | 175 | String1, core::string_view>::value, | |||||
| 176 | bool>::type | 176 | bool>::type | |||||
| 177 | { | 177 | { | |||||
| 178 | // this overload supports forward iterators and | 178 | // this overload supports forward iterators and | |||||
| 179 | // does not assume the existence core::string_view::size | 179 | // does not assume the existence core::string_view::size | |||||
| HITCBC | 180 | 508 | if( detail::type_id<String0>() > | 180 | 508 | if( detail::type_id<String0>() > | ||
| HITCBC | 181 | 254 | detail::type_id<String1>()) | 181 | 254 | detail::type_id<String1>()) | ||
| MISUBC | 182 | ✗ | return detail::ci_is_equal(s1, s0); | 182 | ✗ | return detail::ci_is_equal(s1, s0); | ||
| HITCBC | 183 | 254 | return detail::ci_is_equal(s0, s1); | 183 | 254 | return detail::ci_is_equal(s0, s1); | ||
| 184 | } | 184 | } | |||||
| 185 | 185 | |||||||
| 186 | /** Return true if s0 equals s1 using case-insensitive comparison | 186 | /** Return true if s0 equals s1 using case-insensitive comparison | |||||
| 187 | 187 | |||||||
| 188 | The function is defined only for strings | 188 | The function is defined only for strings | |||||
| 189 | containing low-ASCII characters. | 189 | containing low-ASCII characters. | |||||
| 190 | 190 | |||||||
| 191 | @param s0 The first string | 191 | @param s0 The first string | |||||
| 192 | @param s1 The second string | 192 | @param s1 The second string | |||||
| 193 | @return `true` if `s0` case-insensitively equals `s1`, otherwise `false` | 193 | @return `true` if `s0` case-insensitively equals `s1`, otherwise `false` | |||||
| 194 | 194 | |||||||
| 195 | @par Example | 195 | @par Example | |||||
| 196 | @code | 196 | @code | |||||
| 197 | assert( ci_is_equal( "Boost", "boost" ) ); | 197 | assert( ci_is_equal( "Boost", "boost" ) ); | |||||
| 198 | @endcode | 198 | @endcode | |||||
| 199 | 199 | |||||||
| 200 | @see | 200 | @see | |||||
| 201 | @ref ci_compare, | 201 | @ref ci_compare, | |||||
| 202 | @ref ci_is_less. | 202 | @ref ci_is_less. | |||||
| 203 | */ | 203 | */ | |||||
| 204 | inline | 204 | inline | |||||
| 205 | bool | 205 | bool | |||||
| HITCBC | 206 | 11 | ci_is_equal( | 206 | 11 | ci_is_equal( | ||
| 207 | core::string_view s0, | 207 | core::string_view s0, | |||||
| 208 | core::string_view s1) noexcept | 208 | core::string_view s1) noexcept | |||||
| 209 | { | 209 | { | |||||
| 210 | // this overload is faster as it makes use of | 210 | // this overload is faster as it makes use of | |||||
| 211 | // core::string_view::size | 211 | // core::string_view::size | |||||
| HITCBC | 212 | 11 | if(s0.size() != s1.size()) | 212 | 11 | if(s0.size() != s1.size()) | ||
| HITCBC | 213 | 3 | return false; | 213 | 3 | return false; | ||
| HITCBC | 214 | 8 | return detail::ci_is_equal(s0, s1); | 214 | 8 | return detail::ci_is_equal(s0, s1); | ||
| 215 | } | 215 | } | |||||
| 216 | 216 | |||||||
| 217 | /** Return true if s0 is less than s1 using case-insensitive comparison | 217 | /** Return true if s0 is less than s1 using case-insensitive comparison | |||||
| 218 | 218 | |||||||
| 219 | The comparison algorithm implements a | 219 | The comparison algorithm implements a | |||||
| 220 | case-insensitive total order on the set | 220 | case-insensitive total order on the set | |||||
| 221 | of all strings; however, it is not a | 221 | of all strings; however, it is not a | |||||
| 222 | lexicographical comparison. | 222 | lexicographical comparison. | |||||
| 223 | The function is defined only for strings | 223 | The function is defined only for strings | |||||
| 224 | containing low-ASCII characters. | 224 | containing low-ASCII characters. | |||||
| 225 | 225 | |||||||
| 226 | @param s0 The first string | 226 | @param s0 The first string | |||||
| 227 | @param s1 The second string | 227 | @param s1 The second string | |||||
| 228 | @return `true` if `s0` is case-insensitively less than `s1`, otherwise `false` | 228 | @return `true` if `s0` is case-insensitively less than `s1`, otherwise `false` | |||||
| 229 | 229 | |||||||
| 230 | @par Example | 230 | @par Example | |||||
| 231 | @code | 231 | @code | |||||
| 232 | assert( ! ci_is_less( "Boost", "boost" ) ); | 232 | assert( ! ci_is_less( "Boost", "boost" ) ); | |||||
| 233 | @endcode | 233 | @endcode | |||||
| 234 | 234 | |||||||
| 235 | @see | 235 | @see | |||||
| 236 | @ref ci_compare, | 236 | @ref ci_compare, | |||||
| 237 | @ref ci_is_equal. | 237 | @ref ci_is_equal. | |||||
| 238 | */ | 238 | */ | |||||
| 239 | inline | 239 | inline | |||||
| 240 | bool | 240 | bool | |||||
| HITCBC | 241 | 12 | ci_is_less( | 241 | 12 | ci_is_less( | ||
| 242 | core::string_view s0, | 242 | core::string_view s0, | |||||
| 243 | core::string_view s1) noexcept | 243 | core::string_view s1) noexcept | |||||
| 244 | { | 244 | { | |||||
| HITCBC | 245 | 12 | if(s0.size() != s1.size()) | 245 | 12 | if(s0.size() != s1.size()) | ||
| HITCBC | 246 | 7 | return s0.size() < s1.size(); | 246 | 7 | return s0.size() < s1.size(); | ||
| HITCBC | 247 | 5 | return detail::ci_is_less(s0, s1); | 247 | 5 | return detail::ci_is_less(s0, s1); | ||
| 248 | } | 248 | } | |||||
| 249 | 249 | |||||||
| 250 | //------------------------------------------------ | 250 | //------------------------------------------------ | |||||
| 251 | 251 | |||||||
| 252 | namespace implementation_defined { | 252 | namespace implementation_defined { | |||||
| 253 | struct ci_hash | 253 | struct ci_hash | |||||
| 254 | { | 254 | { | |||||
| 255 | using is_transparent = void; | 255 | using is_transparent = void; | |||||
| 256 | 256 | |||||||
| 257 | std::size_t | 257 | std::size_t | |||||
| HITCBC | 258 | 6 | operator()( | 258 | 6 | operator()( | ||
| 259 | core::string_view s) const noexcept | 259 | core::string_view s) const noexcept | |||||
| 260 | { | 260 | { | |||||
| HITCBC | 261 | 6 | return ci_digest(s); | 261 | 6 | return ci_digest(s); | ||
| 262 | } | 262 | } | |||||
| 263 | }; | 263 | }; | |||||
| 264 | } | 264 | } | |||||
| 265 | 265 | |||||||
| 266 | /** A case-insensitive hash function object for strings | 266 | /** A case-insensitive hash function object for strings | |||||
| 267 | 267 | |||||||
| 268 | The hash function is non-cryptographic and | 268 | The hash function is non-cryptographic and | |||||
| 269 | not hardened against algorithmic complexity | 269 | not hardened against algorithmic complexity | |||||
| 270 | attacks. | 270 | attacks. | |||||
| 271 | This is a suitable hash function for | 271 | This is a suitable hash function for | |||||
| 272 | unordered containers. | 272 | unordered containers. | |||||
| 273 | The function is defined only for strings | 273 | The function is defined only for strings | |||||
| 274 | containing low-ASCII characters. | 274 | containing low-ASCII characters. | |||||
| 275 | 275 | |||||||
| 276 | @par Example | 276 | @par Example | |||||
| 277 | @code | 277 | @code | |||||
| 278 | boost::unordered_map< std::string, std::string, ci_hash, ci_equal > m1; | 278 | boost::unordered_map< std::string, std::string, ci_hash, ci_equal > m1; | |||||
| 279 | 279 | |||||||
| 280 | std::unordered_map < std::string, std::string, ci_hash, ci_equal > m2; // (since C++20) | 280 | std::unordered_map < std::string, std::string, ci_hash, ci_equal > m2; // (since C++20) | |||||
| 281 | @endcode | 281 | @endcode | |||||
| 282 | 282 | |||||||
| 283 | @see | 283 | @see | |||||
| 284 | @ref ci_equal, | 284 | @ref ci_equal, | |||||
| 285 | @ref ci_less. | 285 | @ref ci_less. | |||||
| 286 | */ | 286 | */ | |||||
| 287 | using ci_hash = implementation_defined::ci_hash; | 287 | using ci_hash = implementation_defined::ci_hash; | |||||
| 288 | 288 | |||||||
| 289 | namespace implementation_defined { | 289 | namespace implementation_defined { | |||||
| 290 | struct ci_equal | 290 | struct ci_equal | |||||
| 291 | { | 291 | { | |||||
| 292 | using is_transparent = void; | 292 | using is_transparent = void; | |||||
| 293 | 293 | |||||||
| 294 | template< | 294 | template< | |||||
| 295 | class String0, class String1> | 295 | class String0, class String1> | |||||
| 296 | bool | 296 | bool | |||||
| HITCBC | 297 | 3 | operator()( | 297 | 3 | operator()( | ||
| 298 | String0 const& s0, | 298 | String0 const& s0, | |||||
| 299 | String1 const& s1) const noexcept | 299 | String1 const& s1) const noexcept | |||||
| 300 | { | 300 | { | |||||
| HITCBC | 301 | 3 | return ci_is_equal(s0, s1); | 301 | 3 | return ci_is_equal(s0, s1); | ||
| 302 | } | 302 | } | |||||
| 303 | }; | 303 | }; | |||||
| 304 | } // implementation_defined | 304 | } // implementation_defined | |||||
| 305 | 305 | |||||||
| 306 | /** A case-insensitive equals predicate for strings | 306 | /** A case-insensitive equals predicate for strings | |||||
| 307 | 307 | |||||||
| 308 | The function object returns `true` when | 308 | The function object returns `true` when | |||||
| 309 | two strings are equal, ignoring case. | 309 | two strings are equal, ignoring case. | |||||
| 310 | This is a suitable equality predicate for | 310 | This is a suitable equality predicate for | |||||
| 311 | unordered containers. | 311 | unordered containers. | |||||
| 312 | The function is defined only for strings | 312 | The function is defined only for strings | |||||
| 313 | containing low-ASCII characters. | 313 | containing low-ASCII characters. | |||||
| 314 | 314 | |||||||
| 315 | @par Example | 315 | @par Example | |||||
| 316 | @code | 316 | @code | |||||
| 317 | boost::unordered_map< std::string, std::string, ci_hash, ci_equal > m1; | 317 | boost::unordered_map< std::string, std::string, ci_hash, ci_equal > m1; | |||||
| 318 | 318 | |||||||
| 319 | std::unordered_map < std::string, std::string, ci_hash, ci_equal > m2; // (since C++20) | 319 | std::unordered_map < std::string, std::string, ci_hash, ci_equal > m2; // (since C++20) | |||||
| 320 | @endcode | 320 | @endcode | |||||
| 321 | 321 | |||||||
| 322 | @see | 322 | @see | |||||
| 323 | @ref ci_hash, | 323 | @ref ci_hash, | |||||
| 324 | @ref ci_less. | 324 | @ref ci_less. | |||||
| 325 | */ | 325 | */ | |||||
| 326 | using ci_equal = implementation_defined::ci_equal; | 326 | using ci_equal = implementation_defined::ci_equal; | |||||
| 327 | 327 | |||||||
| 328 | namespace implementation_defined { | 328 | namespace implementation_defined { | |||||
| 329 | struct ci_less | 329 | struct ci_less | |||||
| 330 | { | 330 | { | |||||
| 331 | using is_transparent = void; | 331 | using is_transparent = void; | |||||
| 332 | 332 | |||||||
| 333 | bool | 333 | bool | |||||
| HITCBC | 334 | 4 | operator()( | 334 | 4 | operator()( | ||
| 335 | core::string_view s0, | 335 | core::string_view s0, | |||||
| 336 | core::string_view s1) const noexcept | 336 | core::string_view s1) const noexcept | |||||
| 337 | { | 337 | { | |||||
| HITCBC | 338 | 4 | return ci_is_less(s0, s1); | 338 | 4 | return ci_is_less(s0, s1); | ||
| 339 | } | 339 | } | |||||
| 340 | }; | 340 | }; | |||||
| 341 | } | 341 | } | |||||
| 342 | 342 | |||||||
| 343 | /** A case-insensitive less predicate for strings | 343 | /** A case-insensitive less predicate for strings | |||||
| 344 | 344 | |||||||
| 345 | The comparison algorithm implements a | 345 | The comparison algorithm implements a | |||||
| 346 | case-insensitive total order on the set | 346 | case-insensitive total order on the set | |||||
| 347 | of all ASCII strings; however, it is | 347 | of all ASCII strings; however, it is | |||||
| 348 | not a lexicographical comparison. | 348 | not a lexicographical comparison. | |||||
| 349 | This is a suitable predicate for | 349 | This is a suitable predicate for | |||||
| 350 | ordered containers. | 350 | ordered containers. | |||||
| 351 | The function is defined only for strings | 351 | The function is defined only for strings | |||||
| 352 | containing low-ASCII characters. | 352 | containing low-ASCII characters. | |||||
| 353 | 353 | |||||||
| 354 | @par Example | 354 | @par Example | |||||
| 355 | @code | 355 | @code | |||||
| 356 | boost::container::map< std::string, std::string, ci_less > m1; | 356 | boost::container::map< std::string, std::string, ci_less > m1; | |||||
| 357 | 357 | |||||||
| 358 | std::map< std::string, std::string, ci_less > m2; // (since C++14) | 358 | std::map< std::string, std::string, ci_less > m2; // (since C++14) | |||||
| 359 | @endcode | 359 | @endcode | |||||
| 360 | 360 | |||||||
| 361 | @see | 361 | @see | |||||
| 362 | @ref ci_equal, | 362 | @ref ci_equal, | |||||
| 363 | @ref ci_hash. | 363 | @ref ci_hash. | |||||
| 364 | */ | 364 | */ | |||||
| 365 | using ci_less = implementation_defined::ci_less; | 365 | using ci_less = implementation_defined::ci_less; | |||||
| 366 | 366 | |||||||
| 367 | } // grammar | 367 | } // grammar | |||||
| 368 | } // urls | 368 | } // urls | |||||
| 369 | } // boost | 369 | } // boost | |||||
| 370 | 370 | |||||||
| 371 | #endif | 371 | #endif | |||||