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