• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
38 namespace 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>
starts_with(const Range1T & Input,const Range2T & Test,PredicateT Comp)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>
starts_with(const Range1T & Input,const Range2T & Test)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>
istarts_with(const Range1T & Input,const Range2T & Test,const std::locale & Loc=std::locale ())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>
ends_with(const Range1T & Input,const Range2T & Test,PredicateT Comp)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>
ends_with(const Range1T & Input,const Range2T & Test)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>
iends_with(const Range1T & Input,const Range2T & Test,const std::locale & Loc=std::locale ())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>
contains(const Range1T & Input,const Range2T & Test,PredicateT Comp)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>
contains(const Range1T & Input,const Range2T & Test)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>
icontains(const Range1T & Input,const Range2T & Test,const std::locale & Loc=std::locale ())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>
equals(const Range1T & Input,const Range2T & Test,PredicateT Comp)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>
equals(const Range1T & Input,const Range2T & Test)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>
iequals(const Range1T & Input,const Range2T & Test,const std::locale & Loc=std::locale ())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>
lexicographical_compare(const Range1T & Arg1,const Range2T & Arg2,PredicateT Pred)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>
lexicographical_compare(const Range1T & Arg1,const Range2T & Arg2)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>
ilexicographical_compare(const Range1T & Arg1,const Range2T & Arg2,const std::locale & Loc=std::locale ())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>
all(const RangeT & Input,PredicateT Pred)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