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

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