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
37namespace 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 inline bool starts_with(
58 const Range1T& Input,
59 const Range2T& Test,
60 PredicateT Comp)
61 {
62 iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range1T>::type> lit_input(::boost::as_literal(Input));
63 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 Iterator1T InputEnd=::boost::end(lit_input);
71 Iterator2T TestEnd=::boost::end(lit_test);
72
73 Iterator1T it=::boost::begin(lit_input);
74 Iterator2T pit=::boost::begin(lit_test);
75 for(;
76 it!=InputEnd && pit!=TestEnd;
77 ++it,++pit)
78 {
79 if( !(Comp(*it,*pit)) )
80 return false;
81 }
82
83 return pit==TestEnd;
84 }
85
86 //! 'Starts with' predicate
87 /*!
88 \overload
89 */
90 template<typename Range1T, typename Range2T>
91 inline bool starts_with(
92 const Range1T& Input,
93 const Range2T& Test)
94 {
95 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 inline bool ends_with(
140 const Range1T& Input,
141 const Range2T& Test,
142 PredicateT Comp)
143 {
144 iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range1T>::type> lit_input(::boost::as_literal(Input));
145 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 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 inline bool ends_with(
169 const Range1T& Input,
170 const Range2T& Test)
171 {
172 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 inline bool contains(
214 const Range1T& Input,
215 const Range2T& Test,
216 PredicateT Comp)
217 {
218 iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range1T>::type> lit_input(::boost::as_literal(Input));
219 iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range2T>::type> lit_test(::boost::as_literal(Test));
220
221 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 bool bResult=(::boost::algorithm::first_finder(lit_test,Comp)(::boost::begin(lit_input), ::boost::end(lit_input)));
229 return bResult;
230 }
231
232 //! 'Contains' predicate
233 /*!
234 \overload
235 */
236 template<typename Range1T, typename Range2T>
237 inline bool contains(
238 const Range1T& Input,
239 const Range2T& Test)
240 {
241 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 inline bool equals(
285 const Range1T& Input,
286 const Range2T& Test,
287 PredicateT Comp)
288 {
289 iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range1T>::type> lit_input(::boost::as_literal(Input));
290 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 Iterator1T InputEnd=::boost::end(lit_input);
298 Iterator2T TestEnd=::boost::end(lit_test);
299
300 Iterator1T it=::boost::begin(lit_input);
301 Iterator2T pit=::boost::begin(lit_test);
302 for(;
303 it!=InputEnd && pit!=TestEnd;
304 ++it,++pit)
305 {
306 if( !(Comp(*it,*pit)) )
307 return false;
308 }
309
310 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 inline bool iequals(
342 const Range1T& Input,
343 const Range2T& Test,
344 const std::locale& Loc=std::locale())
345 {
346 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
476

source code of boost/boost/algorithm/string/predicate.hpp