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