predicate.hpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. // Boost string_algo library predicate.hpp header file ---------------------------//
  2. // Copyright Pavol Droba 2002-2003.
  3. //
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. // See http://www.boost.org/ for updates, documentation, and revision history.
  8. #ifndef BOOST_STRING_PREDICATE_HPP
  9. #define BOOST_STRING_PREDICATE_HPP
  10. #include <iterator>
  11. #include <boost/algorithm/string/config.hpp>
  12. #include <boost/range/begin.hpp>
  13. #include <boost/range/end.hpp>
  14. #include <boost/range/iterator.hpp>
  15. #include <boost/range/const_iterator.hpp>
  16. #include <boost/range/as_literal.hpp>
  17. #include <boost/range/iterator_range_core.hpp>
  18. #include <boost/algorithm/string/compare.hpp>
  19. #include <boost/algorithm/string/find.hpp>
  20. #include <boost/algorithm/string/detail/predicate.hpp>
  21. /*! \file boost/algorithm/string/predicate.hpp
  22. Defines string-related predicates.
  23. The predicates determine whether a substring is contained in the input string
  24. under various conditions: a string starts with the substring, ends with the
  25. substring, simply contains the substring or if both strings are equal.
  26. Additionaly the algorithm \c all() checks all elements of a container to satisfy a
  27. condition.
  28. All predicates provide the strong exception guarantee.
  29. */
  30. namespace boost {
  31. namespace algorithm {
  32. // starts_with predicate -----------------------------------------------//
  33. //! 'Starts with' predicate
  34. /*!
  35. This predicate holds when the test string is a prefix of the Input.
  36. In other words, if the input starts with the test.
  37. When the optional predicate is specified, it is used for character-wise
  38. comparison.
  39. \param Input An input sequence
  40. \param Test A test sequence
  41. \param Comp An element comparison predicate
  42. \return The result of the test
  43. \note This function provides the strong exception-safety guarantee
  44. */
  45. template<typename Range1T, typename Range2T, typename PredicateT>
  46. inline bool starts_with(
  47. const Range1T& Input,
  48. const Range2T& Test,
  49. PredicateT Comp)
  50. {
  51. iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range1T>::type> lit_input(::boost::as_literal(Input));
  52. iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range2T>::type> lit_test(::boost::as_literal(Test));
  53. typedef BOOST_STRING_TYPENAME
  54. range_const_iterator<Range1T>::type Iterator1T;
  55. typedef BOOST_STRING_TYPENAME
  56. range_const_iterator<Range2T>::type Iterator2T;
  57. Iterator1T InputEnd=::boost::end(lit_input);
  58. Iterator2T TestEnd=::boost::end(lit_test);
  59. Iterator1T it=::boost::begin(lit_input);
  60. Iterator2T pit=::boost::begin(lit_test);
  61. for(;
  62. it!=InputEnd && pit!=TestEnd;
  63. ++it,++pit)
  64. {
  65. if( !(Comp(*it,*pit)) )
  66. return false;
  67. }
  68. return pit==TestEnd;
  69. }
  70. //! 'Starts with' predicate
  71. /*!
  72. \overload
  73. */
  74. template<typename Range1T, typename Range2T>
  75. inline bool starts_with(
  76. const Range1T& Input,
  77. const Range2T& Test)
  78. {
  79. return ::boost::algorithm::starts_with(Input, Test, is_equal());
  80. }
  81. //! 'Starts with' predicate ( case insensitive )
  82. /*!
  83. This predicate holds when the test string is a prefix of the Input.
  84. In other words, if the input starts with the test.
  85. Elements are compared case insensitively.
  86. \param Input An input sequence
  87. \param Test A test sequence
  88. \param Loc A locale used for case insensitive comparison
  89. \return The result of the test
  90. \note This function provides the strong exception-safety guarantee
  91. */
  92. template<typename Range1T, typename Range2T>
  93. inline bool istarts_with(
  94. const Range1T& Input,
  95. const Range2T& Test,
  96. const std::locale& Loc=std::locale())
  97. {
  98. return ::boost::algorithm::starts_with(Input, Test, is_iequal(Loc));
  99. }
  100. // ends_with predicate -----------------------------------------------//
  101. //! 'Ends with' predicate
  102. /*!
  103. This predicate holds when the test string is a suffix of the Input.
  104. In other words, if the input ends with the test.
  105. When the optional predicate is specified, it is used for character-wise
  106. comparison.
  107. \param Input An input sequence
  108. \param Test A test sequence
  109. \param Comp An element comparison predicate
  110. \return The result of the test
  111. \note This function provides the strong exception-safety guarantee
  112. */
  113. template<typename Range1T, typename Range2T, typename PredicateT>
  114. inline bool ends_with(
  115. const Range1T& Input,
  116. const Range2T& Test,
  117. PredicateT Comp)
  118. {
  119. iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range1T>::type> lit_input(::boost::as_literal(Input));
  120. iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range2T>::type> lit_test(::boost::as_literal(Test));
  121. typedef BOOST_STRING_TYPENAME
  122. range_const_iterator<Range1T>::type Iterator1T;
  123. typedef BOOST_STRING_TYPENAME
  124. std::iterator_traits<Iterator1T>::iterator_category category;
  125. return detail::
  126. ends_with_iter_select(
  127. ::boost::begin(lit_input),
  128. ::boost::end(lit_input),
  129. ::boost::begin(lit_test),
  130. ::boost::end(lit_test),
  131. Comp,
  132. category());
  133. }
  134. //! 'Ends with' predicate
  135. /*!
  136. \overload
  137. */
  138. template<typename Range1T, typename Range2T>
  139. inline bool ends_with(
  140. const Range1T& Input,
  141. const Range2T& Test)
  142. {
  143. return ::boost::algorithm::ends_with(Input, Test, is_equal());
  144. }
  145. //! 'Ends with' predicate ( case insensitive )
  146. /*!
  147. This predicate holds when the test container is a suffix of the Input.
  148. In other words, if the input ends with the test.
  149. Elements are compared case insensitively.
  150. \param Input An input sequence
  151. \param Test A test sequence
  152. \param Loc A locale used for case insensitive comparison
  153. \return The result of the test
  154. \note This function provides the strong exception-safety guarantee
  155. */
  156. template<typename Range1T, typename Range2T>
  157. inline bool iends_with(
  158. const Range1T& Input,
  159. const Range2T& Test,
  160. const std::locale& Loc=std::locale())
  161. {
  162. return ::boost::algorithm::ends_with(Input, Test, is_iequal(Loc));
  163. }
  164. // contains predicate -----------------------------------------------//
  165. //! 'Contains' predicate
  166. /*!
  167. This predicate holds when the test container is contained in the Input.
  168. When the optional predicate is specified, it is used for character-wise
  169. comparison.
  170. \param Input An input sequence
  171. \param Test A test sequence
  172. \param Comp An element comparison predicate
  173. \return The result of the test
  174. \note This function provides the strong exception-safety guarantee
  175. */
  176. template<typename Range1T, typename Range2T, typename PredicateT>
  177. inline bool contains(
  178. const Range1T& Input,
  179. const Range2T& Test,
  180. PredicateT Comp)
  181. {
  182. iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range1T>::type> lit_input(::boost::as_literal(Input));
  183. iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range2T>::type> lit_test(::boost::as_literal(Test));
  184. if (::boost::empty(lit_test))
  185. {
  186. // Empty range is contained always
  187. return true;
  188. }
  189. // Use the temporary variable to make VACPP happy
  190. bool bResult=(::boost::algorithm::first_finder(lit_test,Comp)(::boost::begin(lit_input), ::boost::end(lit_input)));
  191. return bResult;
  192. }
  193. //! 'Contains' predicate
  194. /*!
  195. \overload
  196. */
  197. template<typename Range1T, typename Range2T>
  198. inline bool contains(
  199. const Range1T& Input,
  200. const Range2T& Test)
  201. {
  202. return ::boost::algorithm::contains(Input, Test, is_equal());
  203. }
  204. //! 'Contains' predicate ( case insensitive )
  205. /*!
  206. This predicate holds when the test container is contained in the Input.
  207. Elements are compared case insensitively.
  208. \param Input An input sequence
  209. \param Test A test sequence
  210. \param Loc A locale used for case insensitive comparison
  211. \return The result of the test
  212. \note This function provides the strong exception-safety guarantee
  213. */
  214. template<typename Range1T, typename Range2T>
  215. inline bool icontains(
  216. const Range1T& Input,
  217. const Range2T& Test,
  218. const std::locale& Loc=std::locale())
  219. {
  220. return ::boost::algorithm::contains(Input, Test, is_iequal(Loc));
  221. }
  222. // equals predicate -----------------------------------------------//
  223. //! 'Equals' predicate
  224. /*!
  225. This predicate holds when the test container is equal to the
  226. input container i.e. all elements in both containers are same.
  227. When the optional predicate is specified, it is used for character-wise
  228. comparison.
  229. \param Input An input sequence
  230. \param Test A test sequence
  231. \param Comp An element comparison predicate
  232. \return The result of the test
  233. \note This is a two-way version of \c std::equal algorithm
  234. \note This function provides the strong exception-safety guarantee
  235. */
  236. template<typename Range1T, typename Range2T, typename PredicateT>
  237. inline bool equals(
  238. const Range1T& Input,
  239. const Range2T& Test,
  240. PredicateT Comp)
  241. {
  242. iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range1T>::type> lit_input(::boost::as_literal(Input));
  243. iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range2T>::type> lit_test(::boost::as_literal(Test));
  244. typedef BOOST_STRING_TYPENAME
  245. range_const_iterator<Range1T>::type Iterator1T;
  246. typedef BOOST_STRING_TYPENAME
  247. range_const_iterator<Range2T>::type Iterator2T;
  248. Iterator1T InputEnd=::boost::end(lit_input);
  249. Iterator2T TestEnd=::boost::end(lit_test);
  250. Iterator1T it=::boost::begin(lit_input);
  251. Iterator2T pit=::boost::begin(lit_test);
  252. for(;
  253. it!=InputEnd && pit!=TestEnd;
  254. ++it,++pit)
  255. {
  256. if( !(Comp(*it,*pit)) )
  257. return false;
  258. }
  259. return (pit==TestEnd) && (it==InputEnd);
  260. }
  261. //! 'Equals' predicate
  262. /*!
  263. \overload
  264. */
  265. template<typename Range1T, typename Range2T>
  266. inline bool equals(
  267. const Range1T& Input,
  268. const Range2T& Test)
  269. {
  270. return ::boost::algorithm::equals(Input, Test, is_equal());
  271. }
  272. //! 'Equals' predicate ( case insensitive )
  273. /*!
  274. This predicate holds when the test container is equal to the
  275. input container i.e. all elements in both containers are same.
  276. Elements are compared case insensitively.
  277. \param Input An input sequence
  278. \param Test A test sequence
  279. \param Loc A locale used for case insensitive comparison
  280. \return The result of the test
  281. \note This is a two-way version of \c std::equal algorithm
  282. \note This function provides the strong exception-safety guarantee
  283. */
  284. template<typename Range1T, typename Range2T>
  285. inline bool iequals(
  286. const Range1T& Input,
  287. const Range2T& Test,
  288. const std::locale& Loc=std::locale())
  289. {
  290. return ::boost::algorithm::equals(Input, Test, is_iequal(Loc));
  291. }
  292. // lexicographical_compare predicate -----------------------------//
  293. //! Lexicographical compare predicate
  294. /*!
  295. This predicate is an overload of std::lexicographical_compare
  296. for range arguments
  297. It check whether the first argument is lexicographically less
  298. then the second one.
  299. If the optional predicate is specified, it is used for character-wise
  300. comparison
  301. \param Arg1 First argument
  302. \param Arg2 Second argument
  303. \param Pred Comparison predicate
  304. \return The result of the test
  305. \note This function provides the strong exception-safety guarantee
  306. */
  307. template<typename Range1T, typename Range2T, typename PredicateT>
  308. inline bool lexicographical_compare(
  309. const Range1T& Arg1,
  310. const Range2T& Arg2,
  311. PredicateT Pred)
  312. {
  313. iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range1T>::type> lit_arg1(::boost::as_literal(Arg1));
  314. iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range2T>::type> lit_arg2(::boost::as_literal(Arg2));
  315. return std::lexicographical_compare(
  316. ::boost::begin(lit_arg1),
  317. ::boost::end(lit_arg1),
  318. ::boost::begin(lit_arg2),
  319. ::boost::end(lit_arg2),
  320. Pred);
  321. }
  322. //! Lexicographical compare predicate
  323. /*!
  324. \overload
  325. */
  326. template<typename Range1T, typename Range2T>
  327. inline bool lexicographical_compare(
  328. const Range1T& Arg1,
  329. const Range2T& Arg2)
  330. {
  331. return ::boost::algorithm::lexicographical_compare(Arg1, Arg2, is_less());
  332. }
  333. //! Lexicographical compare predicate (case-insensitive)
  334. /*!
  335. This predicate is an overload of std::lexicographical_compare
  336. for range arguments.
  337. It check whether the first argument is lexicographically less
  338. then the second one.
  339. Elements are compared case insensitively
  340. \param Arg1 First argument
  341. \param Arg2 Second argument
  342. \param Loc A locale used for case insensitive comparison
  343. \return The result of the test
  344. \note This function provides the strong exception-safety guarantee
  345. */
  346. template<typename Range1T, typename Range2T>
  347. inline bool ilexicographical_compare(
  348. const Range1T& Arg1,
  349. const Range2T& Arg2,
  350. const std::locale& Loc=std::locale())
  351. {
  352. return ::boost::algorithm::lexicographical_compare(Arg1, Arg2, is_iless(Loc));
  353. }
  354. // all predicate -----------------------------------------------//
  355. //! 'All' predicate
  356. /*!
  357. This predicate holds it all its elements satisfy a given
  358. condition, represented by the predicate.
  359. \param Input An input sequence
  360. \param Pred A predicate
  361. \return The result of the test
  362. \note This function provides the strong exception-safety guarantee
  363. */
  364. template<typename RangeT, typename PredicateT>
  365. inline bool all(
  366. const RangeT& Input,
  367. PredicateT Pred)
  368. {
  369. iterator_range<BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> lit_input(::boost::as_literal(Input));
  370. typedef BOOST_STRING_TYPENAME
  371. range_const_iterator<RangeT>::type Iterator1T;
  372. Iterator1T InputEnd=::boost::end(lit_input);
  373. for( Iterator1T It=::boost::begin(lit_input); It!=InputEnd; ++It)
  374. {
  375. if (!Pred(*It))
  376. return false;
  377. }
  378. return true;
  379. }
  380. } // namespace algorithm
  381. // pull names to the boost namespace
  382. using algorithm::starts_with;
  383. using algorithm::istarts_with;
  384. using algorithm::ends_with;
  385. using algorithm::iends_with;
  386. using algorithm::contains;
  387. using algorithm::icontains;
  388. using algorithm::equals;
  389. using algorithm::iequals;
  390. using algorithm::all;
  391. using algorithm::lexicographical_compare;
  392. using algorithm::ilexicographical_compare;
  393. } // namespace boost
  394. #endif // BOOST_STRING_PREDICATE_HPP