string_view_base.hpp 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147
  1. //
  2. // Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.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. #ifndef BOOST_URL_GRAMMAR_STRING_VIEW_BASE_HPP
  10. #define BOOST_URL_GRAMMAR_STRING_VIEW_BASE_HPP
  11. #include <boost/url/detail/config.hpp>
  12. #include <boost/url/detail/string_view.hpp>
  13. #include <boost/core/detail/string_view.hpp>
  14. #include <cstddef>
  15. #include <iterator>
  16. #include <string>
  17. #include <type_traits>
  18. #include <utility>
  19. namespace boost {
  20. namespace urls {
  21. namespace grammar {
  22. /** Common functionality for string views
  23. This base class is used to provide common
  24. member functions for reference types that
  25. behave like string views. This cannot be
  26. instantiated directly; instead, derive
  27. from the type and provide constructors
  28. which offer any desired preconditions
  29. and invariants.
  30. */
  31. class string_view_base
  32. {
  33. protected:
  34. /** The referenced character buffer
  35. */
  36. core::string_view s_;
  37. /** Constructor
  38. @param s The string view
  39. */
  40. constexpr
  41. string_view_base(
  42. core::string_view s) noexcept
  43. : s_(s)
  44. {
  45. }
  46. /** Constructor
  47. @param data The character buffer
  48. @param size The number of characters
  49. */
  50. constexpr
  51. string_view_base(
  52. char const* data,
  53. std::size_t size) noexcept
  54. : s_(data, size)
  55. {
  56. }
  57. /** Swap
  58. @param s The object to swap with
  59. */
  60. // VFALCO No idea why this fails in msvc
  61. /*BOOST_CXX14_CONSTEXPR*/
  62. void
  63. swap(
  64. string_view_base& s ) noexcept
  65. {
  66. std::swap(s_, s.s_);
  67. }
  68. /** Constructor
  69. */
  70. string_view_base() = default;
  71. /** Constructor
  72. */
  73. string_view_base(
  74. string_view_base const&) = default;
  75. /** Assignment
  76. @param other The object to assign
  77. @return A reference to this object
  78. */
  79. string_view_base& operator=(
  80. string_view_base const& other) = default;
  81. public:
  82. /// The character traits
  83. typedef std::char_traits<char> traits_type;
  84. /// The value type
  85. typedef char value_type;
  86. /// The pointer type
  87. typedef char* pointer;
  88. /// The const pointer type
  89. typedef char const* const_pointer;
  90. /// The reference type
  91. typedef char& reference;
  92. /// The const reference type
  93. typedef char const& const_reference;
  94. /// The const iterator type
  95. typedef char const* const_iterator;
  96. /// The iterator type
  97. typedef const_iterator iterator;
  98. /// The const reverse iterator type
  99. typedef std::reverse_iterator<
  100. const_iterator> const_reverse_iterator;
  101. /// The reverse iterator type
  102. typedef const_reverse_iterator reverse_iterator;
  103. /// The size type
  104. typedef std::size_t size_type;
  105. /// The difference type
  106. typedef std::ptrdiff_t difference_type;
  107. /// A constant used to represent "no position"
  108. static constexpr std::size_t npos = core::string_view::npos;
  109. //--------------------------------------------
  110. /** Conversion
  111. @return A string view with the same contents
  112. */
  113. operator
  114. core::string_view() const noexcept
  115. {
  116. return s_;
  117. }
  118. /** Conversion
  119. @return A string view with the same contents
  120. */
  121. #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
  122. operator
  123. std::string_view() const noexcept
  124. {
  125. return std::string_view(s_);
  126. }
  127. #endif
  128. /** Conversion
  129. Conversion to std::string is explicit
  130. because assigning to string using an
  131. implicit constructor does not preserve
  132. capacity.
  133. @return A string with the same contents
  134. */
  135. explicit
  136. operator
  137. std::string() const noexcept
  138. {
  139. return std::string(s_);
  140. }
  141. //--------------------------------------------
  142. // iterator support
  143. /** Return an iterator to the beginning
  144. See `core::string_view::begin`
  145. @return An iterator to the beginning
  146. */
  147. BOOST_CONSTEXPR const_iterator begin() const noexcept
  148. {
  149. return s_.begin();
  150. }
  151. /** Return an iterator to the end
  152. See `core::string_view::end`
  153. @return An iterator to the end
  154. */
  155. BOOST_CONSTEXPR const_iterator end() const noexcept
  156. {
  157. return s_.end();
  158. }
  159. /** Return an iterator to the beginning
  160. See `core::string_view::cbegin`
  161. @return An iterator to the beginning
  162. */
  163. BOOST_CONSTEXPR const_iterator cbegin() const noexcept
  164. {
  165. return s_.cbegin();
  166. }
  167. /** Return an iterator to the end
  168. See `core::string_view::cend`
  169. @return An iterator to the end
  170. */
  171. BOOST_CONSTEXPR const_iterator cend() const noexcept
  172. {
  173. return s_.cend();
  174. }
  175. /** Return a reverse iterator to the end
  176. See `core::string_view::rbegin`
  177. @return A reverse iterator to the end
  178. */
  179. BOOST_URL_LIB_ARRAY_CONSTEXPR
  180. const_reverse_iterator rbegin() const noexcept
  181. {
  182. return s_.rbegin();
  183. }
  184. /** Return a reverse iterator to the beginning
  185. See `core::string_view::rend`
  186. @return A reverse iterator to the beginning
  187. */
  188. BOOST_URL_LIB_ARRAY_CONSTEXPR
  189. const_reverse_iterator rend() const noexcept
  190. {
  191. return s_.rend();
  192. }
  193. /** Return a reverse iterator to the end
  194. See `core::string_view::crbegin`
  195. @return A reverse iterator to the end
  196. */
  197. BOOST_URL_LIB_ARRAY_CONSTEXPR
  198. const_reverse_iterator crbegin() const noexcept
  199. {
  200. return s_.crbegin();
  201. }
  202. /** Return a reverse iterator to the beginning
  203. See `core::string_view::crend`
  204. @return A reverse iterator to the beginning
  205. */
  206. BOOST_URL_LIB_ARRAY_CONSTEXPR
  207. const_reverse_iterator crend() const noexcept
  208. {
  209. return s_.crend();
  210. }
  211. // capacity
  212. /** Return the size
  213. See `core::string_view::size`
  214. @return The size
  215. */
  216. BOOST_CONSTEXPR size_type size() const noexcept
  217. {
  218. return s_.size();
  219. }
  220. /** Return the size
  221. See `core::string_view::length`
  222. @return The size
  223. */
  224. BOOST_CONSTEXPR size_type length() const noexcept
  225. {
  226. return s_.length();
  227. }
  228. /** Return the maximum allowed size
  229. See `core::string_view::max_size`
  230. @return The maximum allowed size
  231. */
  232. BOOST_CONSTEXPR size_type max_size() const noexcept
  233. {
  234. return s_.max_size();
  235. }
  236. /** Return true if the string is empty
  237. See `core::string_view::size`
  238. @return `true` if the string is empty
  239. */
  240. BOOST_CONSTEXPR bool empty() const noexcept
  241. {
  242. return s_.empty();
  243. }
  244. // element access
  245. /** Access a character
  246. See `core::string_view::operator[]`
  247. @param pos The position to access
  248. @return The character at the position
  249. */
  250. BOOST_CXX14_CONSTEXPR const_reference
  251. operator[]( size_type pos ) const noexcept
  252. {
  253. return s_[pos];
  254. }
  255. /** Access a character
  256. See `core::string_view::at`
  257. @param pos The position to access
  258. @return The character at the position
  259. */
  260. BOOST_CXX14_CONSTEXPR const_reference
  261. at( size_type pos ) const
  262. {
  263. return s_.at(pos);
  264. }
  265. /** Return the first character
  266. See `core::string_view::front`
  267. @return The first character
  268. */
  269. BOOST_CXX14_CONSTEXPR const_reference
  270. front() const noexcept
  271. {
  272. return s_.front();
  273. }
  274. /** Return the last character
  275. See `core::string_view::back`
  276. @return The last character
  277. */
  278. BOOST_CXX14_CONSTEXPR const_reference
  279. back() const noexcept
  280. {
  281. return s_.back();
  282. }
  283. /** Return a pointer to the character buffer
  284. See `core::string_view::data`
  285. @return A pointer to the character buffer
  286. */
  287. BOOST_CONSTEXPR const_pointer
  288. data() const noexcept
  289. {
  290. return s_.data();
  291. }
  292. // string operations
  293. /** Copy the characters to another buffer
  294. See `core::string_view::copy`
  295. @param s The destination buffer
  296. @param n The number of characters to copy
  297. @param pos The position to start from
  298. @return The number of characters copied
  299. */
  300. BOOST_CXX14_CONSTEXPR size_type copy(
  301. char* s, size_type n, size_type pos = 0 ) const
  302. {
  303. return s_.copy(s, n, pos);
  304. }
  305. /** Return a view to part of the string
  306. See `core::string_view::substr`
  307. @param pos The position to start from
  308. @param n The number of characters
  309. @return A view to the substring
  310. */
  311. BOOST_CXX14_CONSTEXPR core::string_view substr(
  312. size_type pos = 0, size_type n = core::string_view::npos ) const
  313. {
  314. return s_.substr(pos, n);
  315. }
  316. // comparison
  317. /** Return the result of comparing to another string
  318. See `core::string_view::compare`
  319. @param str The string to compare
  320. @return The result of the comparison
  321. */
  322. BOOST_CXX14_CONSTEXPR int
  323. compare( core::string_view str ) const noexcept
  324. {
  325. return s_.compare(str);
  326. }
  327. /** Return the result of comparing to another string
  328. See `core::string_view::compare`
  329. @param pos1 The position to start comparing from
  330. @param n1 The number of characters to compare
  331. @param str The string to compare
  332. @return The result of the comparison
  333. */
  334. BOOST_CONSTEXPR int compare(
  335. size_type pos1, size_type n1, core::string_view str ) const
  336. {
  337. return s_.compare(pos1, n1, str);
  338. }
  339. /** Return the result of comparing to another string
  340. See `core::string_view::compare`
  341. @param pos1 The position to start comparing from
  342. @param n1 The number of characters to compare
  343. @param str The string to compare
  344. @param pos2 The position to start comparing from
  345. @param n2 The number of characters to compare
  346. @return The result of the comparison
  347. */
  348. BOOST_CONSTEXPR int compare(
  349. size_type pos1, size_type n1, core::string_view str,
  350. size_type pos2, size_type n2 ) const
  351. {
  352. return s_.compare(pos1, n1, str, pos2, n2);
  353. }
  354. /** Return the result of comparing to another string
  355. See `core::string_view::compare`
  356. @param s The string to compare
  357. @return The result of the comparison
  358. */
  359. BOOST_CONSTEXPR int compare(
  360. char const* s ) const noexcept
  361. {
  362. return s_.compare(s);
  363. }
  364. /** Return the result of comparing to another string
  365. See `core::string_view::compare`
  366. @param pos1 The position to start comparing from
  367. @param n1 The number of characters to compare
  368. @param s The string to compare
  369. @return The result of the comparison
  370. */
  371. BOOST_CONSTEXPR int compare(
  372. size_type pos1, size_type n1, char const* s ) const
  373. {
  374. return s_.compare(pos1, n1, s);
  375. }
  376. /** Return the result of comparing to another string
  377. See `core::string_view::compare`
  378. @param pos1 The position to start comparing from
  379. @param n1 The number of characters to compare
  380. @param s The string to compare
  381. @param n2 The number of characters to compare
  382. @return The result of the comparison
  383. */
  384. BOOST_CONSTEXPR int compare(
  385. size_type pos1, size_type n1,
  386. char const* s, size_type n2 ) const
  387. {
  388. return s_.compare(pos1, n1, s, n2);
  389. }
  390. // starts_with
  391. /** Return true if a matching prefix exists
  392. See `core::string_view::starts_with`
  393. @param x The string to search for
  394. @return `true` if the prefix matches
  395. */
  396. BOOST_CONSTEXPR bool starts_with(
  397. core::string_view x ) const noexcept
  398. {
  399. return s_.starts_with(x);
  400. }
  401. /** Return true if a matching prefix exists
  402. See `core::string_view::starts_with`
  403. @param x The character to search for
  404. @return `true` if the prefix matches
  405. */
  406. BOOST_CONSTEXPR bool starts_with(
  407. char x ) const noexcept
  408. {
  409. return s_.starts_with(x);
  410. }
  411. /** Return true if a matching prefix exists
  412. See `core::string_view::starts_with`
  413. @param x The string to search for
  414. @return `true` if the prefix matches
  415. */
  416. BOOST_CONSTEXPR bool starts_with(
  417. char const* x ) const noexcept
  418. {
  419. return s_.starts_with(x);
  420. }
  421. // ends_with
  422. /** Return true if a matching suffix exists
  423. See `core::string_view::ends_with`
  424. @param x The string to search for
  425. @return `true` if the suffix matches
  426. */
  427. BOOST_CONSTEXPR bool ends_with(
  428. core::string_view x ) const noexcept
  429. {
  430. return s_.ends_with(x);
  431. }
  432. /** Return true if a matching suffix exists
  433. See `core::string_view::ends_with`
  434. @param x The character to search for
  435. @return `true` if the suffix matches
  436. */
  437. BOOST_CONSTEXPR bool ends_with(
  438. char x ) const noexcept
  439. {
  440. return s_.ends_with(x);
  441. }
  442. /** Return true if a matching suffix exists
  443. See `core::string_view::ends_with`
  444. @param x The string to search for
  445. @return `true` if the suffix matches
  446. */
  447. BOOST_CONSTEXPR bool ends_with(
  448. char const* x ) const noexcept
  449. {
  450. return s_.ends_with(x);
  451. }
  452. // find
  453. /** Return the position of matching characters
  454. See `core::string_view::find`
  455. @param str The characters to search for
  456. @param pos The position to start searching from
  457. @return The position of the first match
  458. */
  459. BOOST_CONSTEXPR size_type find(
  460. core::string_view str, size_type pos = 0 ) const noexcept
  461. {
  462. return s_.find(str, pos);
  463. }
  464. /** Return the position of matching characters
  465. See `core::string_view::find`
  466. @param c The character to search for
  467. @param pos The position to start searching from
  468. @return The position of the first match
  469. */
  470. BOOST_CXX14_CONSTEXPR size_type find(
  471. char c, size_type pos = 0 ) const noexcept
  472. {
  473. return s_.find(c, pos);
  474. }
  475. /** Return the position of matching characters
  476. See `core::string_view::find`
  477. @param s The characters to search for
  478. @param pos The position to start searching from
  479. @param n The number of characters to search for
  480. @return The position of the first match
  481. */
  482. BOOST_CXX14_CONSTEXPR size_type find(
  483. char const* s, size_type pos, size_type n ) const noexcept
  484. {
  485. return s_.find(s, pos, n);
  486. }
  487. /** Return the position of matching characters
  488. See `core::string_view::find`
  489. @param s The characters to search for
  490. @param pos The position to start searching from
  491. @return The position of the first match
  492. */
  493. BOOST_CONSTEXPR size_type find(
  494. char const* s, size_type pos = 0 ) const noexcept
  495. {
  496. return s_.find(s, pos);
  497. }
  498. // rfind
  499. /** Return the position of matching characters
  500. See `core::string_view::rfind`
  501. @param str The characters to search for
  502. @param pos The position to start searching from
  503. @return The position of the first match
  504. */
  505. BOOST_CONSTEXPR size_type rfind(
  506. core::string_view str, size_type pos = core::string_view::npos ) const noexcept
  507. {
  508. return s_.rfind(str, pos);
  509. }
  510. /** Return the position of matching characters
  511. See `core::string_view::rfind`
  512. @param c The character to search for
  513. @param pos The position to start searching from
  514. @return The position of the first match
  515. */
  516. BOOST_CXX14_CONSTEXPR size_type rfind(
  517. char c, size_type pos = core::string_view::npos ) const noexcept
  518. {
  519. return s_.rfind(c, pos);
  520. }
  521. /** Return the position of matching characters
  522. See `core::string_view::rfind`
  523. @param s The characters to search for
  524. @param pos The position to start searching from
  525. @param n The number of characters to search for
  526. @return The position of the first match
  527. */
  528. BOOST_CXX14_CONSTEXPR size_type rfind(
  529. char const* s, size_type pos, size_type n ) const noexcept
  530. {
  531. return s_.rfind(s, pos, n);
  532. }
  533. /** Return the position of matching characters
  534. See `core::string_view::rfind`
  535. @param s The characters to search for
  536. @param pos The position to start searching from
  537. @return The position of the first match
  538. */
  539. BOOST_CONSTEXPR size_type rfind(
  540. char const* s, size_type pos = core::string_view::npos ) const noexcept
  541. {
  542. return s_.rfind(s, pos);
  543. }
  544. // find_first_of
  545. /** Return the position of the first match
  546. See `core::string_view::find_first_of`
  547. @param str The characters to search for
  548. @param pos The position to start searching from
  549. @return The position of the first match
  550. */
  551. BOOST_CXX14_CONSTEXPR size_type find_first_of(
  552. core::string_view str, size_type pos = 0 ) const noexcept
  553. {
  554. return s_.find_first_of(str, pos);
  555. }
  556. /** Return the position of the first match
  557. See `core::string_view::find_first_of`
  558. @param c The character to search for
  559. @param pos The position to start searching from
  560. @return The position of the first match
  561. */
  562. BOOST_CONSTEXPR size_type find_first_of(
  563. char c, size_type pos = 0 ) const noexcept
  564. {
  565. return s_.find_first_of(c, pos);
  566. }
  567. /** Return the position of the first match
  568. See `core::string_view::find_first_of`
  569. @param s The characters to search for
  570. @param pos The position to start searching from
  571. @param n The number of characters to search for
  572. @return The position of the first match
  573. */
  574. BOOST_CXX14_CONSTEXPR size_type find_first_of(
  575. char const* s, size_type pos, size_type n ) const noexcept
  576. {
  577. return s_.find_first_of(s, pos, n);
  578. }
  579. /** Return the position of the first match
  580. See `core::string_view::find_first_of`
  581. @param s The characters to search for
  582. @param pos The position to start searching from
  583. @return The position of the first match
  584. */
  585. BOOST_CXX14_CONSTEXPR size_type find_first_of(
  586. char const* s, size_type pos = 0 ) const noexcept
  587. {
  588. return s_.find_first_of(s, pos);
  589. }
  590. // find_last_of
  591. /** Return the position of the last match
  592. See `core::string_view::find_last_of`
  593. @param str The characters to search for
  594. @param pos The position to start searching from
  595. @return The position of the last match
  596. */
  597. BOOST_CXX14_CONSTEXPR size_type find_last_of(
  598. core::string_view str, size_type pos = core::string_view::npos ) const noexcept
  599. {
  600. return s_.find_last_of(str, pos);
  601. }
  602. /** Return the position of the last match
  603. See `core::string_view::find_last_of`
  604. @param c The character to search for
  605. @param pos The position to start searching from
  606. @return The position of the last match
  607. */
  608. BOOST_CONSTEXPR size_type find_last_of(
  609. char c, size_type pos = core::string_view::npos ) const noexcept
  610. {
  611. return s_.find_last_of(c, pos);
  612. }
  613. /** Return the position of the last match
  614. See `core::string_view::find_last_of`
  615. @param s The characters to search for
  616. @param pos The position to start searching from
  617. @param n The number of characters to search for
  618. @return The position of the last match
  619. */
  620. BOOST_CXX14_CONSTEXPR size_type find_last_of(
  621. char const* s, size_type pos, size_type n ) const noexcept
  622. {
  623. return s_.find_last_of(s, pos, n);
  624. }
  625. /** Return the position of the last match
  626. See `core::string_view::find_last_of`
  627. @param s The characters to search for
  628. @param pos The position to start searching from
  629. @return The position of the last match
  630. */
  631. BOOST_CXX14_CONSTEXPR size_type find_last_of(
  632. char const* s, size_type pos = core::string_view::npos ) const noexcept
  633. {
  634. return s_.find_last_of(s, pos);
  635. }
  636. // find_first_not_of
  637. /** Return the position of the first non-match
  638. See `core::string_view::find_first_not_of`
  639. @param str The characters to search for
  640. @param pos The position to start searching from
  641. @return The position of the first non-match
  642. */
  643. BOOST_CXX14_CONSTEXPR size_type find_first_not_of(
  644. core::string_view str, size_type pos = 0 ) const noexcept
  645. {
  646. return s_.find_first_not_of(str, pos);
  647. }
  648. /** Return the position of the first non-match
  649. See `core::string_view::find_first_not_of`
  650. @param c The character to search for
  651. @param pos The position to start searching from
  652. @return The position of the first non-match
  653. */
  654. BOOST_CXX14_CONSTEXPR size_type find_first_not_of(
  655. char c, size_type pos = 0 ) const noexcept
  656. {
  657. return s_.find_first_not_of(c, pos);
  658. }
  659. /** Return the position of the first non-match
  660. See `core::string_view::find_first_not_of`
  661. @param s The characters to search for
  662. @param pos The position to start searching from
  663. @param n The number of characters to search for
  664. @return The position of the first non-match
  665. */
  666. BOOST_CXX14_CONSTEXPR size_type find_first_not_of(
  667. char const* s, size_type pos, size_type n ) const noexcept
  668. {
  669. return s_.find_first_not_of(s, pos, n);
  670. }
  671. /** Return the position of the first non-match
  672. See `core::string_view::find_first_not_of`
  673. @param s The characters to search for
  674. @param pos The position to start searching from
  675. @return The position of the first non-match
  676. */
  677. BOOST_CXX14_CONSTEXPR size_type find_first_not_of(
  678. char const* s, size_type pos = 0 ) const noexcept
  679. {
  680. return s_.find_first_not_of(s, pos);
  681. }
  682. // find_last_not_of
  683. /** Return the position of the last non-match
  684. See `core::string_view::find_last_not_of`
  685. @param str The characters to search for
  686. @param pos The position to start searching from
  687. @return The position of the last non-match
  688. */
  689. BOOST_CXX14_CONSTEXPR size_type find_last_not_of(
  690. core::string_view str, size_type pos = core::string_view::npos ) const noexcept
  691. {
  692. return s_.find_last_not_of(str, pos);
  693. }
  694. /** Return the position of the last non-match
  695. See `core::string_view::find_last_not_of`
  696. @param c The character to search for
  697. @param pos The position to start searching from
  698. @return The position of the last non-match
  699. */
  700. BOOST_CXX14_CONSTEXPR size_type find_last_not_of(
  701. char c, size_type pos = core::string_view::npos ) const noexcept
  702. {
  703. return s_.find_last_not_of(c, pos);
  704. }
  705. /** Return the position of the last non-match
  706. See `core::string_view::find_last_not_of`
  707. @param s The characters to search for
  708. @param pos The position to start searching from
  709. @param n The number of characters to search for
  710. @return The position of the last non-match
  711. */
  712. BOOST_CXX14_CONSTEXPR size_type find_last_not_of(
  713. char const* s, size_type pos, size_type n ) const noexcept
  714. {
  715. return s_.find_last_not_of(s, pos, n);
  716. }
  717. /** Return the position of the last non-match
  718. See `core::string_view::find_last_not_of`
  719. @param s The characters to search for
  720. @param pos The position to start searching from
  721. @return The position of the last non-match
  722. */
  723. BOOST_CXX14_CONSTEXPR size_type find_last_not_of(
  724. char const* s, size_type pos = core::string_view::npos ) const noexcept
  725. {
  726. return s_.find_last_not_of(s, pos);
  727. }
  728. // contains
  729. /** Return true if matching characters are found
  730. See `core::string_view::contains`
  731. @param sv The string to search for
  732. @return `true` if the string contains the characters, otherwise `false`
  733. */
  734. BOOST_CONSTEXPR bool contains( core::string_view sv ) const noexcept
  735. {
  736. return s_.contains(sv);
  737. }
  738. /** Return true if matching characters are found
  739. See `core::string_view::contains`
  740. @param c The character to search for
  741. @return `true` if the string contains the character, otherwise `false`
  742. */
  743. BOOST_CXX14_CONSTEXPR bool contains( char c ) const noexcept
  744. {
  745. return s_.contains(c);
  746. }
  747. /** Return true if matching characters are found
  748. See `core::string_view::contains`
  749. @param s The string to search for
  750. @return `true` if the string contains the characters, otherwise `false`
  751. */
  752. BOOST_CONSTEXPR bool contains( char const* s ) const noexcept
  753. {
  754. return s_.contains(s);
  755. }
  756. // relational operators
  757. #ifndef BOOST_URL_DOCS
  758. private:
  759. template<class S0, class S1>
  760. using is_match = std::integral_constant<bool,
  761. std::is_convertible<S0, core::string_view>::value &&
  762. std::is_convertible<S1, core::string_view>::value && (
  763. (std::is_base_of<string_view_base,
  764. typename std::decay<S0>::type>::value &&
  765. std::is_convertible<S0 const volatile*,
  766. string_view_base const volatile*>::value) ||
  767. (std::is_base_of<string_view_base,
  768. typename std::decay<S1>::type>::value &&
  769. std::is_convertible<S1 const volatile*,
  770. string_view_base const volatile*>::value))>;
  771. public:
  772. /** Compare two string views for equality
  773. This function is only enabled if both arguments
  774. are convertible to `core::string_view` and at least
  775. one of the arguments is derived from `string_view_base`.
  776. @param s0 The first string
  777. @param s1 The second string
  778. @return `true` if the strings are equal, otherwise `false`
  779. */
  780. template<class S0, class S1>
  781. BOOST_CXX14_CONSTEXPR friend auto operator==(
  782. S0 const& s0, S1 const& s1) noexcept ->
  783. typename std::enable_if<
  784. is_match<S0, S1>::value, bool>::type
  785. {
  786. return urls::detail::to_sv(s0) == urls::detail::to_sv(s1);
  787. }
  788. /** Compare two string views for inequality
  789. This function is only enabled if both arguments
  790. are convertible to `core::string_view` and at least
  791. one of the arguments is derived from `string_view_base`.
  792. @param s0 The first string
  793. @param s1 The second string
  794. @return `true` if the strings are not equal, otherwise `false`
  795. */
  796. template<class S0, class S1>
  797. BOOST_CXX14_CONSTEXPR friend auto operator!=(
  798. S0 const& s0, S1 const& s1) noexcept ->
  799. typename std::enable_if<
  800. is_match<S0, S1>::value, bool>::type
  801. {
  802. return urls::detail::to_sv(s0) != urls::detail::to_sv(s1);
  803. }
  804. /** Compare two string views for less than
  805. This function is only enabled if both arguments
  806. are convertible to `core::string_view` and at least
  807. one of the arguments is derived from `string_view_base`.
  808. @param s0 The first string
  809. @param s1 The second string
  810. @return `true` if the first string is less than the second, otherwise `false`
  811. */
  812. template<class S0, class S1>
  813. BOOST_CXX14_CONSTEXPR friend auto operator<(
  814. S0 const& s0, S1 const& s1) noexcept ->
  815. typename std::enable_if<
  816. is_match<S0, S1>::value, bool>::type
  817. {
  818. return urls::detail::to_sv(s0) < urls::detail::to_sv(s1);
  819. }
  820. /** Compare two string views for less than or equal
  821. This function is only enabled if both arguments
  822. are convertible to `core::string_view` and at least
  823. one of the arguments is derived from `string_view_base`.
  824. @param s0 The first string
  825. @param s1 The second string
  826. @return `true` if the first string is less than or equal to the second, otherwise `false`
  827. */
  828. template<class S0, class S1>
  829. BOOST_CXX14_CONSTEXPR friend auto operator<=(
  830. S0 const& s0, S1 const& s1) noexcept ->
  831. typename std::enable_if<
  832. is_match<S0, S1>::value, bool>::type
  833. {
  834. return urls::detail::to_sv(s0) <= urls::detail::to_sv(s1);
  835. }
  836. /** Compare two string views for greater than
  837. This function is only enabled if both arguments
  838. are convertible to `core::string_view` and at least
  839. one of the arguments is derived from `string_view_base`.
  840. @param s0 The first string
  841. @param s1 The second string
  842. @return `true` if the first string is greater than the second, otherwise `false`
  843. */
  844. template<class S0, class S1>
  845. BOOST_CXX14_CONSTEXPR friend auto operator>(
  846. S0 const& s0, S1 const& s1) noexcept ->
  847. typename std::enable_if<
  848. is_match<S0, S1>::value, bool>::type
  849. {
  850. return urls::detail::to_sv(s0) > urls::detail::to_sv(s1);
  851. }
  852. /** Compare two string views for greater than or equal
  853. This function is only enabled if both arguments
  854. are convertible to `core::string_view` and at least
  855. one of the arguments is derived from `string_view_base`.
  856. @param s0 The first string
  857. @param s1 The second string
  858. @return `true` if the first string is greater than or equal to the second, otherwise `false`
  859. */
  860. template<class S0, class S1>
  861. BOOST_CXX14_CONSTEXPR friend auto operator>=(
  862. S0 const& s0, S1 const& s1) noexcept ->
  863. typename std::enable_if<
  864. is_match<S0, S1>::value, bool>::type
  865. {
  866. return urls::detail::to_sv(s0) >= urls::detail::to_sv(s1);
  867. }
  868. #endif
  869. //--------------------------------------------
  870. /** Format a string to an output stream
  871. @param os The output stream to write to
  872. @param s The string to write
  873. @return A reference to the output stream, for chaining
  874. */
  875. BOOST_URL_DECL
  876. friend
  877. std::ostream&
  878. operator<<(
  879. std::ostream& os,
  880. string_view_base const& s);
  881. };
  882. //------------------------------------------------
  883. /** Format a string to an output stream
  884. */
  885. BOOST_URL_DECL
  886. std::ostream&
  887. operator<<(
  888. std::ostream& os,
  889. string_view_base const& s);
  890. } // grammar
  891. #ifndef BOOST_URL_DOCS
  892. namespace detail {
  893. template <>
  894. inline
  895. core::string_view
  896. to_sv(grammar::string_view_base const& s) noexcept
  897. {
  898. return s.operator core::string_view();
  899. }
  900. } // detail
  901. #endif
  902. } // urls
  903. } // boost
  904. #endif