Bug Summary

File:usr/include/boost/algorithm/string/detail/classification.hpp
Warning:line 137, column 25
Potential memory leak

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name test_to_element.cc -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/home/fedora/workspace/kea-dev/clang-static-analyzer/src/lib/testutils -fcoverage-compilation-dir=/home/fedora/workspace/kea-dev/clang-static-analyzer/src/lib/testutils -resource-dir /usr/bin/../lib/clang/19 -D HAVE_CONFIG_H -I . -I ../../.. -I ../../../src/lib -I ../../../src/lib -I /usr/src/googletest/googletest -I /usr/src/googletest/googletest/include -D OS_LINUX -I ../../.. -I ../../.. -D PIC -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/backward -internal-isystem /usr/bin/../lib/clang/19/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/14/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wwrite-strings -Wno-sign-compare -Wno-missing-field-initializers -std=c++20 -fdeprecated-macro -ferror-limit 19 -stack-protector 2 -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/fedora/workspace/kea-dev/clang-static-analyzer/report/2024-12-20-083036-19082-1 -x c++ test_to_element.cc

test_to_element.cc

1// Copyright (C) 2017-2024 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
8
9#include <testutils/test_to_element.h>
10#include <boost/algorithm/string.hpp>
11#include <gtest/gtest.h>
12#include <string>
13#include <vector>
14
15using namespace isc::data;
16using namespace std;
17
18namespace isc {
19namespace test {
20
21void expectEqWithDiff(ConstElementPtr const& a, ConstElementPtr const& b) {
22 ASSERT_TRUE(a)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(a)) ; else return ::testing
::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "test_to_element.cc", 22, ::testing::internal::GetBoolAssertionFailureMessage
( gtest_ar_, "a", "false", "true") .c_str()) = ::testing::Message
()
;
23 ASSERT_TRUE(b)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(b)) ; else return ::testing
::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "test_to_element.cc", 23, ::testing::internal::GetBoolAssertionFailureMessage
( gtest_ar_, "b", "false", "true") .c_str()) = ::testing::Message
()
;
24 string const pretty_print_a(prettyPrint(a));
25 string const pretty_print_b(prettyPrint(b));
26 EXPECT_EQ(pretty_print_a, pretty_print_b)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("pretty_print_a"
, "pretty_print_b", pretty_print_a, pretty_print_b))) ; else ::
testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "test_to_element.cc", 26, gtest_ar.failure_message()) = ::testing
::Message()
27 << endl
28 << "Diff:" << endl
29 << generateDiff(pretty_print_a, pretty_print_b) << endl;
30}
31
32void expectEqWithDiff(ElementPtr const& a, ElementPtr const& b) {
33 ASSERT_TRUE(a)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(a)) ; else return ::testing
::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "test_to_element.cc", 33, ::testing::internal::GetBoolAssertionFailureMessage
( gtest_ar_, "a", "false", "true") .c_str()) = ::testing::Message
()
;
1
Control jumps to 'case 0:' at line 33
2
Assuming the condition is true
3
Taking true branch
34 ASSERT_TRUE(b)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(b)) ; else return ::testing
::internal::AssertHelper(::testing::TestPartResult::kFatalFailure
, "test_to_element.cc", 34, ::testing::internal::GetBoolAssertionFailureMessage
( gtest_ar_, "b", "false", "true") .c_str()) = ::testing::Message
()
;
4
Control jumps to 'case 0:' at line 34
5
Assuming the condition is true
6
Taking true branch
35 string const pretty_print_a(prettyPrint(a));
36 string const pretty_print_b(prettyPrint(b));
37 EXPECT_EQ(pretty_print_a, pretty_print_b)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::EqHelper::Compare("pretty_print_a"
, "pretty_print_b", pretty_print_a, pretty_print_b))) ; else ::
testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "test_to_element.cc", 37, gtest_ar.failure_message()) = ::testing
::Message()
7
Control jumps to 'case 0:' at line 37
8
Assuming the condition is false
9
Taking false branch
38 << endl
39 << "Diff:" << endl
40 << generateDiff(pretty_print_a, pretty_print_b) << endl;
10
Calling 'generateDiff'
41}
42
43#ifdef HAVE_CREATE_UNIFIED_DIFF1
44string generateDiff(string left, string right) {
45 vector<string> left_lines;
46 boost::split(left_lines, left, boost::is_any_of("\n"));
11
Calling 'split<std::vector<std::basic_string<char>>, std::basic_string<char> &, boost::algorithm::detail::is_any_ofF<char>>'
47 vector<string> right_lines;
48 boost::split(right_lines, right, boost::is_any_of("\n"));
49 using namespace testing::internal;
50 return (edit_distance::CreateUnifiedDiff(left_lines, right_lines));
51}
52#else
53std::string generateDiff(std::string, std::string) {
54 return ("N/A: !HAVE_CREATE_UNIFIED_DIFF");
55}
56#endif
57
58} // namespace test
59} // namespace isc

/usr/include/boost/algorithm/string/split.hpp

1// Boost string_algo library split.hpp header file ---------------------------//
2
3// Copyright Pavol Droba 2002-2006.
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_SPLIT_HPP
12#define BOOST_STRING_SPLIT_HPP
13
14#include <boost/algorithm/string/config.hpp>
15
16#include <boost/algorithm/string/iter_find.hpp>
17#include <boost/algorithm/string/finder.hpp>
18#include <boost/algorithm/string/compare.hpp>
19
20/*! \file
21 Defines basic split algorithms.
22 Split algorithms can be used to divide a string
23 into several parts according to given criteria.
24
25 Each part is copied and added as a new element to the
26 output container.
27 Thus the result container must be able to hold copies
28 of the matches (in a compatible structure like std::string) or
29 a reference to it (e.g. using the iterator range class).
30 Examples of such a container are \c std::vector<std::string>
31 or \c std::list<boost::iterator_range<std::string::iterator>>
32*/
33
34namespace boost {
35 namespace algorithm {
36
37// find_all ------------------------------------------------------------//
38
39 //! Find all algorithm
40 /*!
41 This algorithm finds all occurrences of the search string
42 in the input.
43
44 Each part is copied and added as a new element to the
45 output container.
46 Thus the result container must be able to hold copies
47 of the matches (in a compatible structure like std::string) or
48 a reference to it (e.g. using the iterator range class).
49 Examples of such a container are \c std::vector<std::string>
50 or \c std::list<boost::iterator_range<std::string::iterator>>
51
52 \param Result A container that can hold copies of references to the substrings
53 \param Input A container which will be searched.
54 \param Search A substring to be searched for.
55 \return A reference the result
56
57 \note Prior content of the result will be overwritten.
58
59 \note This function provides the strong exception-safety guarantee
60 */
61 template< typename SequenceSequenceT, typename Range1T, typename Range2T >
62 inline SequenceSequenceT& find_all(
63 SequenceSequenceT& Result,
64#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
65 Range1T&& Input,
66#else
67 Range1T& Input,
68#endif
69 const Range2T& Search)
70 {
71 return ::boost::algorithm::iter_find(
72 Result,
73 Input,
74 ::boost::algorithm::first_finder(Search) );
75 }
76
77 //! Find all algorithm ( case insensitive )
78 /*!
79 This algorithm finds all occurrences of the search string
80 in the input.
81 Each part is copied and added as a new element to the
82 output container. Thus the result container must be able to hold copies
83 of the matches (in a compatible structure like std::string) or
84 a reference to it (e.g. using the iterator range class).
85 Examples of such a container are \c std::vector<std::string>
86 or \c std::list<boost::iterator_range<std::string::iterator>>
87
88 Searching is case insensitive.
89
90 \param Result A container that can hold copies of references to the substrings
91 \param Input A container which will be searched.
92 \param Search A substring to be searched for.
93 \param Loc A locale used for case insensitive comparison
94 \return A reference the result
95
96 \note Prior content of the result will be overwritten.
97
98 \note This function provides the strong exception-safety guarantee
99 */
100 template< typename SequenceSequenceT, typename Range1T, typename Range2T >
101 inline SequenceSequenceT& ifind_all(
102 SequenceSequenceT& Result,
103#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
104 Range1T&& Input,
105#else
106 Range1T& Input,
107#endif
108 const Range2T& Search,
109 const std::locale& Loc=std::locale() )
110 {
111 return ::boost::algorithm::iter_find(
112 Result,
113 Input,
114 ::boost::algorithm::first_finder(Search, is_iequal(Loc) ) );
115 }
116
117
118// tokenize -------------------------------------------------------------//
119
120 //! Split algorithm
121 /*!
122 Tokenize expression. This function is equivalent to C strtok. Input
123 sequence is split into tokens, separated by separators. Separators
124 are given by means of the predicate.
125
126 Each part is copied and added as a new element to the
127 output container.
128 Thus the result container must be able to hold copies
129 of the matches (in a compatible structure like std::string) or
130 a reference to it (e.g. using the iterator range class).
131 Examples of such a container are \c std::vector<std::string>
132 or \c std::list<boost::iterator_range<std::string::iterator>>
133
134 \param Result A container that can hold copies of references to the substrings
135 \param Input A container which will be searched.
136 \param Pred A predicate to identify separators. This predicate is
137 supposed to return true if a given element is a separator.
138 \param eCompress If eCompress argument is set to token_compress_on, adjacent
139 separators are merged together. Otherwise, every two separators
140 delimit a token.
141 \return A reference the result
142
143 \note Prior content of the result will be overwritten.
144
145 \note This function provides the strong exception-safety guarantee
146 */
147 template< typename SequenceSequenceT, typename RangeT, typename PredicateT >
148 inline SequenceSequenceT& split(
149 SequenceSequenceT& Result,
150#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
151 RangeT&& Input,
152#else
153 RangeT& Input,
154#endif
155 PredicateT Pred,
156 token_compress_mode_type eCompress=token_compress_off )
157 {
158 return ::boost::algorithm::iter_split(
159 Result,
160 Input,
161 ::boost::algorithm::token_finder( Pred, eCompress ) );
12
Calling 'token_finder<boost::algorithm::detail::is_any_ofF<char>>'
19
Returned allocated memory
20
Calling '~is_any_ofF'
162 }
163
164 } // namespace algorithm
165
166 // pull names to the boost namespace
167 using algorithm::find_all;
168 using algorithm::ifind_all;
169 using algorithm::split;
170
171} // namespace boost
172
173
174#endif // BOOST_STRING_SPLIT_HPP
175

/usr/include/boost/algorithm/string/finder.hpp

1// Boost string_algo library finder.hpp header file ---------------------------//
2
3// Copyright Pavol Droba 2002-2006.
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_FINDER_HPP
12#define BOOST_STRING_FINDER_HPP
13
14#include <boost/algorithm/string/config.hpp>
15
16#include <boost/range/iterator_range_core.hpp>
17#include <boost/range/begin.hpp>
18#include <boost/range/end.hpp>
19#include <boost/range/iterator.hpp>
20#include <boost/range/const_iterator.hpp>
21
22#include <boost/algorithm/string/constants.hpp>
23#include <boost/algorithm/string/detail/finder.hpp>
24#include <boost/algorithm/string/compare.hpp>
25
26/*! \file
27 Defines Finder generators. Finder object is a functor which is able to
28 find a substring matching a specific criteria in the input.
29 Finders are used as a pluggable components for replace, find
30 and split facilities. This header contains generator functions
31 for finders provided in this library.
32*/
33
34namespace boost {
35 namespace algorithm {
36
37// Finder generators ------------------------------------------//
38
39 //! "First" finder
40 /*!
41 Construct the \c first_finder. The finder searches for the first
42 occurrence of the string in a given input.
43 The result is given as an \c iterator_range delimiting the match.
44
45 \param Search A substring to be searched for.
46 \return An instance of the \c first_finder object
47 */
48 template<typename RangeT>
49 inline detail::first_finderF<
50 BOOST_STRING_TYPENAMEtypename range_const_iterator<RangeT>::type,
51 is_equal>
52 first_finder( const RangeT& Search )
53 {
54 return
55 detail::first_finderF<
56 BOOST_STRING_TYPENAMEtypename
57 range_const_iterator<RangeT>::type,
58 is_equal>( ::boost::as_literal(Search), is_equal() ) ;
59 }
60
61 //! "First" finder
62 /*!
63 \overload
64 */
65 template<typename RangeT,typename PredicateT>
66 inline detail::first_finderF<
67 BOOST_STRING_TYPENAMEtypename range_const_iterator<RangeT>::type,
68 PredicateT>
69 first_finder(
70 const RangeT& Search, PredicateT Comp )
71 {
72 return
73 detail::first_finderF<
74 BOOST_STRING_TYPENAMEtypename
75 range_const_iterator<RangeT>::type,
76 PredicateT>( ::boost::as_literal(Search), Comp );
77 }
78
79 //! "Last" finder
80 /*!
81 Construct the \c last_finder. The finder searches for the last
82 occurrence of the string in a given input.
83 The result is given as an \c iterator_range delimiting the match.
84
85 \param Search A substring to be searched for.
86 \return An instance of the \c last_finder object
87 */
88 template<typename RangeT>
89 inline detail::last_finderF<
90 BOOST_STRING_TYPENAMEtypename range_const_iterator<RangeT>::type,
91 is_equal>
92 last_finder( const RangeT& Search )
93 {
94 return
95 detail::last_finderF<
96 BOOST_STRING_TYPENAMEtypename
97 range_const_iterator<RangeT>::type,
98 is_equal>( ::boost::as_literal(Search), is_equal() );
99 }
100 //! "Last" finder
101 /*!
102 \overload
103 */
104 template<typename RangeT, typename PredicateT>
105 inline detail::last_finderF<
106 BOOST_STRING_TYPENAMEtypename range_const_iterator<RangeT>::type,
107 PredicateT>
108 last_finder( const RangeT& Search, PredicateT Comp )
109 {
110 return
111 detail::last_finderF<
112 BOOST_STRING_TYPENAMEtypename
113 range_const_iterator<RangeT>::type,
114 PredicateT>( ::boost::as_literal(Search), Comp ) ;
115 }
116
117 //! "Nth" finder
118 /*!
119 Construct the \c nth_finder. The finder searches for the n-th (zero-indexed)
120 occurrence of the string in a given input.
121 The result is given as an \c iterator_range delimiting the match.
122
123 \param Search A substring to be searched for.
124 \param Nth An index of the match to be find
125 \return An instance of the \c nth_finder object
126 */
127 template<typename RangeT>
128 inline detail::nth_finderF<
129 BOOST_STRING_TYPENAMEtypename range_const_iterator<RangeT>::type,
130 is_equal>
131 nth_finder(
132 const RangeT& Search,
133 int Nth)
134 {
135 return
136 detail::nth_finderF<
137 BOOST_STRING_TYPENAMEtypename
138 range_const_iterator<RangeT>::type,
139 is_equal>( ::boost::as_literal(Search), Nth, is_equal() ) ;
140 }
141 //! "Nth" finder
142 /*!
143 \overload
144 */
145 template<typename RangeT, typename PredicateT>
146 inline detail::nth_finderF<
147 BOOST_STRING_TYPENAMEtypename range_const_iterator<RangeT>::type,
148 PredicateT>
149 nth_finder(
150 const RangeT& Search,
151 int Nth,
152 PredicateT Comp )
153 {
154 return
155 detail::nth_finderF<
156 BOOST_STRING_TYPENAMEtypename
157 range_const_iterator<RangeT>::type,
158 PredicateT>( ::boost::as_literal(Search), Nth, Comp );
159 }
160
161 //! "Head" finder
162 /*!
163 Construct the \c head_finder. The finder returns a head of a given
164 input. The head is a prefix of a string up to n elements in
165 size. If an input has less then n elements, whole input is
166 considered a head.
167 The result is given as an \c iterator_range delimiting the match.
168
169 \param N The size of the head
170 \return An instance of the \c head_finder object
171 */
172 inline detail::head_finderF
173 head_finder( int N )
174 {
175 return detail::head_finderF(N);
176 }
177
178 //! "Tail" finder
179 /*!
180 Construct the \c tail_finder. The finder returns a tail of a given
181 input. The tail is a suffix of a string up to n elements in
182 size. If an input has less then n elements, whole input is
183 considered a head.
184 The result is given as an \c iterator_range delimiting the match.
185
186 \param N The size of the head
187 \return An instance of the \c tail_finder object
188 */
189 inline detail::tail_finderF
190 tail_finder( int N )
191 {
192 return detail::tail_finderF(N);
193 }
194
195 //! "Token" finder
196 /*!
197 Construct the \c token_finder. The finder searches for a token
198 specified by a predicate. It is similar to std::find_if
199 algorithm, with an exception that it return a range of
200 instead of a single iterator.
201
202 If "compress token mode" is enabled, adjacent matching tokens are
203 concatenated into one match. Thus the finder can be used to
204 search for continuous segments of characters satisfying the
205 given predicate.
206
207 The result is given as an \c iterator_range delimiting the match.
208
209 \param Pred An element selection predicate
210 \param eCompress Compress flag
211 \return An instance of the \c token_finder object
212 */
213 template< typename PredicateT >
214 inline detail::token_finderF<PredicateT>
215 token_finder(
216 PredicateT Pred,
217 token_compress_mode_type eCompress=token_compress_off )
218 {
219 return detail::token_finderF<PredicateT>( Pred, eCompress );
13
Calling constructor for 'token_finderF<boost::algorithm::detail::is_any_ofF<char>>'
18
Returning from constructor for 'token_finderF<boost::algorithm::detail::is_any_ofF<char>>'
220 }
221
222 //! "Range" finder
223 /*!
224 Construct the \c range_finder. The finder does not perform
225 any operation. It simply returns the given range for
226 any input.
227
228 \param Begin Beginning of the range
229 \param End End of the range
230 \return An instance of the \c range_finger object
231 */
232 template< typename ForwardIteratorT >
233 inline detail::range_finderF<ForwardIteratorT>
234 range_finder(
235 ForwardIteratorT Begin,
236 ForwardIteratorT End )
237 {
238 return detail::range_finderF<ForwardIteratorT>( Begin, End );
239 }
240
241 //! "Range" finder
242 /*!
243 \overload
244 */
245 template< typename ForwardIteratorT >
246 inline detail::range_finderF<ForwardIteratorT>
247 range_finder( iterator_range<ForwardIteratorT> Range )
248 {
249 return detail::range_finderF<ForwardIteratorT>( Range );
250 }
251
252 } // namespace algorithm
253
254 // pull the names to the boost namespace
255 using algorithm::first_finder;
256 using algorithm::last_finder;
257 using algorithm::nth_finder;
258 using algorithm::head_finder;
259 using algorithm::tail_finder;
260 using algorithm::token_finder;
261 using algorithm::range_finder;
262
263} // namespace boost
264
265
266#endif // BOOST_STRING_FINDER_HPP

/usr/include/boost/algorithm/string/detail/finder.hpp

1// Boost string_algo library finder.hpp header file ---------------------------//
2
3// Copyright Pavol Droba 2002-2006.
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_FINDER_DETAIL_HPP
12#define BOOST_STRING_FINDER_DETAIL_HPP
13
14#include <boost/algorithm/string/config.hpp>
15#include <boost/algorithm/string/constants.hpp>
16#include <iterator>
17
18#include <boost/range/iterator_range_core.hpp>
19#include <boost/range/begin.hpp>
20#include <boost/range/end.hpp>
21#include <boost/range/empty.hpp>
22#include <boost/range/as_literal.hpp>
23
24namespace boost {
25 namespace algorithm {
26 namespace detail {
27
28
29// find first functor -----------------------------------------------//
30
31 // find a subsequence in the sequence ( functor )
32 /*
33 Returns a pair <begin,end> marking the subsequence in the sequence.
34 If the find fails, functor returns <End,End>
35 */
36 template<typename SearchIteratorT,typename PredicateT>
37 struct first_finderF
38 {
39 typedef SearchIteratorT search_iterator_type;
40
41 // Construction
42 template< typename SearchT >
43 first_finderF( const SearchT& Search, PredicateT Comp ) :
44 m_Search(::boost::begin(Search), ::boost::end(Search)), m_Comp(Comp) {}
45 first_finderF(
46 search_iterator_type SearchBegin,
47 search_iterator_type SearchEnd,
48 PredicateT Comp ) :
49 m_Search(SearchBegin, SearchEnd), m_Comp(Comp) {}
50
51 // Operation
52 template< typename ForwardIteratorT >
53 iterator_range<ForwardIteratorT>
54 operator()(
55 ForwardIteratorT Begin,
56 ForwardIteratorT End ) const
57 {
58 typedef iterator_range<ForwardIteratorT> result_type;
59 typedef ForwardIteratorT input_iterator_type;
60
61 // Outer loop
62 for(input_iterator_type OuterIt=Begin;
63 OuterIt!=End;
64 ++OuterIt)
65 {
66 // Sanity check
67 if( boost::empty(m_Search) )
68 return result_type( End, End );
69
70 input_iterator_type InnerIt=OuterIt;
71 search_iterator_type SubstrIt=m_Search.begin();
72 for(;
73 InnerIt!=End && SubstrIt!=m_Search.end();
74 ++InnerIt,++SubstrIt)
75 {
76 if( !( m_Comp(*InnerIt,*SubstrIt) ) )
77 break;
78 }
79
80 // Substring matching succeeded
81 if ( SubstrIt==m_Search.end() )
82 return result_type( OuterIt, InnerIt );
83 }
84
85 return result_type( End, End );
86 }
87
88 private:
89 iterator_range<search_iterator_type> m_Search;
90 PredicateT m_Comp;
91 };
92
93// find last functor -----------------------------------------------//
94
95 // find the last match a subsequence in the sequence ( functor )
96 /*
97 Returns a pair <begin,end> marking the subsequence in the sequence.
98 If the find fails, returns <End,End>
99 */
100 template<typename SearchIteratorT, typename PredicateT>
101 struct last_finderF
102 {
103 typedef SearchIteratorT search_iterator_type;
104 typedef first_finderF<
105 search_iterator_type,
106 PredicateT> first_finder_type;
107
108 // Construction
109 template< typename SearchT >
110 last_finderF( const SearchT& Search, PredicateT Comp ) :
111 m_Search(::boost::begin(Search), ::boost::end(Search)), m_Comp(Comp) {}
112 last_finderF(
113 search_iterator_type SearchBegin,
114 search_iterator_type SearchEnd,
115 PredicateT Comp ) :
116 m_Search(SearchBegin, SearchEnd), m_Comp(Comp) {}
117
118 // Operation
119 template< typename ForwardIteratorT >
120 iterator_range<ForwardIteratorT>
121 operator()(
122 ForwardIteratorT Begin,
123 ForwardIteratorT End ) const
124 {
125 typedef iterator_range<ForwardIteratorT> result_type;
126
127 if( boost::empty(m_Search) )
128 return result_type( End, End );
129
130 typedef BOOST_STRING_TYPENAMEtypename
131 std::iterator_traits<ForwardIteratorT>::iterator_category category;
132
133 return findit( Begin, End, category() );
134 }
135
136 private:
137 // forward iterator
138 template< typename ForwardIteratorT >
139 iterator_range<ForwardIteratorT>
140 findit(
141 ForwardIteratorT Begin,
142 ForwardIteratorT End,
143 std::forward_iterator_tag ) const
144 {
145 typedef iterator_range<ForwardIteratorT> result_type;
146
147 first_finder_type first_finder(
148 m_Search.begin(), m_Search.end(), m_Comp );
149
150 result_type M=first_finder( Begin, End );
151 result_type Last=M;
152
153 while( M )
154 {
155 Last=M;
156 M=first_finder( ::boost::end(M), End );
157 }
158
159 return Last;
160 }
161
162 // bidirectional iterator
163 template< typename ForwardIteratorT >
164 iterator_range<ForwardIteratorT>
165 findit(
166 ForwardIteratorT Begin,
167 ForwardIteratorT End,
168 std::bidirectional_iterator_tag ) const
169 {
170 typedef iterator_range<ForwardIteratorT> result_type;
171 typedef ForwardIteratorT input_iterator_type;
172
173 // Outer loop
174 for(input_iterator_type OuterIt=End;
175 OuterIt!=Begin; )
176 {
177 input_iterator_type OuterIt2=--OuterIt;
178
179 input_iterator_type InnerIt=OuterIt2;
180 search_iterator_type SubstrIt=m_Search.begin();
181 for(;
182 InnerIt!=End && SubstrIt!=m_Search.end();
183 ++InnerIt,++SubstrIt)
184 {
185 if( !( m_Comp(*InnerIt,*SubstrIt) ) )
186 break;
187 }
188
189 // Substring matching succeeded
190 if( SubstrIt==m_Search.end() )
191 return result_type( OuterIt2, InnerIt );
192 }
193
194 return result_type( End, End );
195 }
196
197 private:
198 iterator_range<search_iterator_type> m_Search;
199 PredicateT m_Comp;
200 };
201
202// find n-th functor -----------------------------------------------//
203
204 // find the n-th match of a subsequence in the sequence ( functor )
205 /*
206 Returns a pair <begin,end> marking the subsequence in the sequence.
207 If the find fails, returns <End,End>
208 */
209 template<typename SearchIteratorT, typename PredicateT>
210 struct nth_finderF
211 {
212 typedef SearchIteratorT search_iterator_type;
213 typedef first_finderF<
214 search_iterator_type,
215 PredicateT> first_finder_type;
216 typedef last_finderF<
217 search_iterator_type,
218 PredicateT> last_finder_type;
219
220 // Construction
221 template< typename SearchT >
222 nth_finderF(
223 const SearchT& Search,
224 int Nth,
225 PredicateT Comp) :
226 m_Search(::boost::begin(Search), ::boost::end(Search)),
227 m_Nth(Nth),
228 m_Comp(Comp) {}
229 nth_finderF(
230 search_iterator_type SearchBegin,
231 search_iterator_type SearchEnd,
232 int Nth,
233 PredicateT Comp) :
234 m_Search(SearchBegin, SearchEnd),
235 m_Nth(Nth),
236 m_Comp(Comp) {}
237
238 // Operation
239 template< typename ForwardIteratorT >
240 iterator_range<ForwardIteratorT>
241 operator()(
242 ForwardIteratorT Begin,
243 ForwardIteratorT End ) const
244 {
245 if(m_Nth>=0)
246 {
247 return find_forward(Begin, End, m_Nth);
248 }
249 else
250 {
251 return find_backward(Begin, End, -m_Nth);
252 }
253
254 }
255
256 private:
257 // Implementation helpers
258 template< typename ForwardIteratorT >
259 iterator_range<ForwardIteratorT>
260 find_forward(
261 ForwardIteratorT Begin,
262 ForwardIteratorT End,
263 unsigned int N) const
264 {
265 typedef iterator_range<ForwardIteratorT> result_type;
266
267 // Sanity check
268 if( boost::empty(m_Search) )
269 return result_type( End, End );
270
271 // Instantiate find functor
272 first_finder_type first_finder(
273 m_Search.begin(), m_Search.end(), m_Comp );
274
275 result_type M( Begin, Begin );
276
277 for( unsigned int n=0; n<=N; ++n )
278 {
279 // find next match
280 M=first_finder( ::boost::end(M), End );
281
282 if ( !M )
283 {
284 // Subsequence not found, return
285 return M;
286 }
287 }
288
289 return M;
290 }
291
292 template< typename ForwardIteratorT >
293 iterator_range<ForwardIteratorT>
294 find_backward(
295 ForwardIteratorT Begin,
296 ForwardIteratorT End,
297 unsigned int N) const
298 {
299 typedef iterator_range<ForwardIteratorT> result_type;
300
301 // Sanity check
302 if( boost::empty(m_Search) )
303 return result_type( End, End );
304
305 // Instantiate find functor
306 last_finder_type last_finder(
307 m_Search.begin(), m_Search.end(), m_Comp );
308
309 result_type M( End, End );
310
311 for( unsigned int n=1; n<=N; ++n )
312 {
313 // find next match
314 M=last_finder( Begin, ::boost::begin(M) );
315
316 if ( !M )
317 {
318 // Subsequence not found, return
319 return M;
320 }
321 }
322
323 return M;
324 }
325
326
327 private:
328 iterator_range<search_iterator_type> m_Search;
329 int m_Nth;
330 PredicateT m_Comp;
331 };
332
333// find head/tail implementation helpers ---------------------------//
334
335 template<typename ForwardIteratorT>
336 iterator_range<ForwardIteratorT>
337 find_head_impl(
338 ForwardIteratorT Begin,
339 ForwardIteratorT End,
340 unsigned int N,
341 std::forward_iterator_tag )
342 {
343 typedef ForwardIteratorT input_iterator_type;
344 typedef iterator_range<ForwardIteratorT> result_type;
345
346 input_iterator_type It=Begin;
347 for( unsigned int Index=0; Index<N && It!=End; ++Index,++It )
348 ;
349
350 return result_type( Begin, It );
351 }
352
353 template< typename ForwardIteratorT >
354 iterator_range<ForwardIteratorT>
355 find_head_impl(
356 ForwardIteratorT Begin,
357 ForwardIteratorT End,
358 unsigned int N,
359 std::random_access_iterator_tag )
360 {
361 typedef iterator_range<ForwardIteratorT> result_type;
362
363 if ( (End<=Begin) || ( static_cast<unsigned int>(End-Begin) < N ) )
364 return result_type( Begin, End );
365
366 return result_type(Begin,Begin+N);
367 }
368
369 // Find head implementation
370 template<typename ForwardIteratorT>
371 iterator_range<ForwardIteratorT>
372 find_head_impl(
373 ForwardIteratorT Begin,
374 ForwardIteratorT End,
375 unsigned int N )
376 {
377 typedef BOOST_STRING_TYPENAMEtypename
378 std::iterator_traits<ForwardIteratorT>::iterator_category category;
379
380 return ::boost::algorithm::detail::find_head_impl( Begin, End, N, category() );
381 }
382
383 template< typename ForwardIteratorT >
384 iterator_range<ForwardIteratorT>
385 find_tail_impl(
386 ForwardIteratorT Begin,
387 ForwardIteratorT End,
388 unsigned int N,
389 std::forward_iterator_tag )
390 {
391 typedef ForwardIteratorT input_iterator_type;
392 typedef iterator_range<ForwardIteratorT> result_type;
393
394 unsigned int Index=0;
395 input_iterator_type It=Begin;
396 input_iterator_type It2=Begin;
397
398 // Advance It2 by N increments
399 for( Index=0; Index<N && It2!=End; ++Index,++It2 )
400 ;
401
402 // Advance It, It2 to the end
403 for(; It2!=End; ++It,++It2 )
404 ;
405
406 return result_type( It, It2 );
407 }
408
409 template< typename ForwardIteratorT >
410 iterator_range<ForwardIteratorT>
411 find_tail_impl(
412 ForwardIteratorT Begin,
413 ForwardIteratorT End,
414 unsigned int N,
415 std::bidirectional_iterator_tag )
416 {
417 typedef ForwardIteratorT input_iterator_type;
418 typedef iterator_range<ForwardIteratorT> result_type;
419
420 input_iterator_type It=End;
421 for( unsigned int Index=0; Index<N && It!=Begin; ++Index,--It )
422 ;
423
424 return result_type( It, End );
425 }
426
427 template< typename ForwardIteratorT >
428 iterator_range<ForwardIteratorT>
429 find_tail_impl(
430 ForwardIteratorT Begin,
431 ForwardIteratorT End,
432 unsigned int N,
433 std::random_access_iterator_tag )
434 {
435 typedef iterator_range<ForwardIteratorT> result_type;
436
437 if ( (End<=Begin) || ( static_cast<unsigned int>(End-Begin) < N ) )
438 return result_type( Begin, End );
439
440 return result_type( End-N, End );
441 }
442
443 // Operation
444 template< typename ForwardIteratorT >
445 iterator_range<ForwardIteratorT>
446 find_tail_impl(
447 ForwardIteratorT Begin,
448 ForwardIteratorT End,
449 unsigned int N )
450 {
451 typedef BOOST_STRING_TYPENAMEtypename
452 std::iterator_traits<ForwardIteratorT>::iterator_category category;
453
454 return ::boost::algorithm::detail::find_tail_impl( Begin, End, N, category() );
455 }
456
457
458
459// find head functor -----------------------------------------------//
460
461
462 // find a head in the sequence ( functor )
463 /*
464 This functor find a head of the specified range. For
465 a specified N, the head is a subsequence of N starting
466 elements of the range.
467 */
468 struct head_finderF
469 {
470 // Construction
471 head_finderF( int N ) : m_N(N) {}
472
473 // Operation
474 template< typename ForwardIteratorT >
475 iterator_range<ForwardIteratorT>
476 operator()(
477 ForwardIteratorT Begin,
478 ForwardIteratorT End ) const
479 {
480 if(m_N>=0)
481 {
482 return ::boost::algorithm::detail::find_head_impl( Begin, End, m_N );
483 }
484 else
485 {
486 iterator_range<ForwardIteratorT> Res=
487 ::boost::algorithm::detail::find_tail_impl( Begin, End, -m_N );
488
489 return ::boost::make_iterator_range(Begin, Res.begin());
490 }
491 }
492
493 private:
494 int m_N;
495 };
496
497// find tail functor -----------------------------------------------//
498
499
500 // find a tail in the sequence ( functor )
501 /*
502 This functor find a tail of the specified range. For
503 a specified N, the head is a subsequence of N starting
504 elements of the range.
505 */
506 struct tail_finderF
507 {
508 // Construction
509 tail_finderF( int N ) : m_N(N) {}
510
511 // Operation
512 template< typename ForwardIteratorT >
513 iterator_range<ForwardIteratorT>
514 operator()(
515 ForwardIteratorT Begin,
516 ForwardIteratorT End ) const
517 {
518 if(m_N>=0)
519 {
520 return ::boost::algorithm::detail::find_tail_impl( Begin, End, m_N );
521 }
522 else
523 {
524 iterator_range<ForwardIteratorT> Res=
525 ::boost::algorithm::detail::find_head_impl( Begin, End, -m_N );
526
527 return ::boost::make_iterator_range(Res.end(), End);
528 }
529 }
530
531 private:
532 int m_N;
533 };
534
535// find token functor -----------------------------------------------//
536
537 // find a token in a sequence ( functor )
538 /*
539 This find functor finds a token specified be a predicate
540 in a sequence. It is equivalent of std::find algorithm,
541 with an exception that it return range instead of a single
542 iterator.
543
544 If bCompress is set to true, adjacent matching tokens are
545 concatenated into one match.
546 */
547 template< typename PredicateT >
548 struct token_finderF
549 {
550 // Construction
551 token_finderF(
552 PredicateT Pred,
553 token_compress_mode_type eCompress=token_compress_off ) :
554 m_Pred(Pred), m_eCompress(eCompress) {}
14
Calling copy constructor for 'is_any_ofF<char>'
17
Returning from copy constructor for 'is_any_ofF<char>'
555
556 // Operation
557 template< typename ForwardIteratorT >
558 iterator_range<ForwardIteratorT>
559 operator()(
560 ForwardIteratorT Begin,
561 ForwardIteratorT End ) const
562 {
563 typedef iterator_range<ForwardIteratorT> result_type;
564
565 ForwardIteratorT It=std::find_if( Begin, End, m_Pred );
566
567 if( It==End )
568 {
569 return result_type( End, End );
570 }
571 else
572 {
573 ForwardIteratorT It2=It;
574
575 if( m_eCompress==token_compress_on )
576 {
577 // Find first non-matching character
578 while( It2!=End && m_Pred(*It2) ) ++It2;
579 }
580 else
581 {
582 // Advance by one position
583 ++It2;
584 }
585
586 return result_type( It, It2 );
587 }
588 }
589
590 private:
591 PredicateT m_Pred;
592 token_compress_mode_type m_eCompress;
593 };
594
595// find range functor -----------------------------------------------//
596
597 // find a range in the sequence ( functor )
598 /*
599 This functor actually does not perform any find operation.
600 It always returns given iterator range as a result.
601 */
602 template<typename ForwardIterator1T>
603 struct range_finderF
604 {
605 typedef ForwardIterator1T input_iterator_type;
606 typedef iterator_range<input_iterator_type> result_type;
607
608 // Construction
609 range_finderF(
610 input_iterator_type Begin,
611 input_iterator_type End ) : m_Range(Begin, End) {}
612
613 range_finderF(const iterator_range<input_iterator_type>& Range) :
614 m_Range(Range) {}
615
616 // Operation
617 template< typename ForwardIterator2T >
618 iterator_range<ForwardIterator2T>
619 operator()(
620 ForwardIterator2T,
621 ForwardIterator2T ) const
622 {
623#if BOOST_WORKAROUND( __MWERKS__, <= 0x3003 )((1 + 0 == 0) && (__MWERKS__ != 0) && (1 % ((
(__MWERKS__ <= 0x3003) ) + 1)))
624 return iterator_range<const ForwardIterator2T>(this->m_Range);
625#else
626 return m_Range;
627#endif
628 }
629
630 private:
631 iterator_range<input_iterator_type> m_Range;
632 };
633
634
635 } // namespace detail
636 } // namespace algorithm
637} // namespace boost
638
639#endif // BOOST_STRING_FINDER_DETAIL_HPP

/usr/include/boost/algorithm/string/detail/classification.hpp

1// Boost string_algo library classification.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_CLASSIFICATION_DETAIL_HPP
12#define BOOST_STRING_CLASSIFICATION_DETAIL_HPP
13
14#include <boost/algorithm/string/config.hpp>
15#include <algorithm>
16#include <cstring>
17#include <functional>
18#include <locale>
19
20#include <boost/range/begin.hpp>
21#include <boost/range/distance.hpp>
22#include <boost/range/end.hpp>
23
24#include <boost/algorithm/string/predicate_facade.hpp>
25#include <boost/type_traits/remove_const.hpp>
26
27namespace boost {
28 namespace algorithm {
29 namespace detail {
30
31// classification functors -----------------------------------------------//
32
33 // is_classified functor
34 struct is_classifiedF :
35 public predicate_facade<is_classifiedF>
36 {
37 // Boost.ResultOf support
38 typedef bool result_type;
39
40 // Constructor from a locale
41 is_classifiedF(std::ctype_base::mask Type, std::locale const & Loc = std::locale()) :
42 m_Type(Type), m_Locale(Loc) {}
43 // Operation
44 template<typename CharT>
45 bool operator()( CharT Ch ) const
46 {
47 return std::use_facet< std::ctype<CharT> >(m_Locale).is( m_Type, Ch );
48 }
49
50 #if defined(BOOST_BORLANDC) && (BOOST_BORLANDC >= 0x560) && (BOOST_BORLANDC <= 0x582) && !defined(_USE_OLD_RW_STL)
51 template<>
52 bool operator()( char const Ch ) const
53 {
54 return std::use_facet< std::ctype<char> >(m_Locale).is( m_Type, Ch );
55 }
56 #endif
57
58 private:
59 std::ctype_base::mask m_Type;
60 std::locale m_Locale;
61 };
62
63
64 // is_any_of functor
65 /*
66 returns true if the value is from the specified set
67 */
68 template<typename CharT>
69 struct is_any_ofF :
70 public predicate_facade<is_any_ofF<CharT> >
71 {
72 private:
73 // set cannot operate on const value-type
74 typedef typename ::boost::remove_const<CharT>::type set_value_type;
75
76 public:
77 // Boost.ResultOf support
78 typedef bool result_type;
79
80 // Constructor
81 template<typename RangeT>
82 is_any_ofF( const RangeT& Range ) : m_Size(0)
83 {
84 // Prepare storage
85 m_Storage.m_dynSet=0;
86
87 std::size_t Size=::boost::distance(Range);
88 m_Size=Size;
89 set_value_type* Storage=0;
90
91 if(use_fixed_storage(m_Size))
92 {
93 // Use fixed storage
94 Storage=&m_Storage.m_fixSet[0];
95 }
96 else
97 {
98 // Use dynamic storage
99 m_Storage.m_dynSet=new set_value_type[m_Size];
100 Storage=m_Storage.m_dynSet;
101 }
102
103 // Use fixed storage
104 ::std::copy(::boost::begin(Range), ::boost::end(Range), Storage);
105 ::std::sort(Storage, Storage+m_Size);
106 }
107
108 // Copy constructor
109 is_any_ofF(const is_any_ofF& Other) : m_Size(Other.m_Size)
110 {
111 // Prepare storage
112 m_Storage.m_dynSet=0;
113 const set_value_type* SrcStorage=0;
114 set_value_type* DestStorage=0;
115
116 if(use_fixed_storage(m_Size))
15
Taking false branch
117 {
118 // Use fixed storage
119 DestStorage=&m_Storage.m_fixSet[0];
120 SrcStorage=&Other.m_Storage.m_fixSet[0];
121 }
122 else
123 {
124 // Use dynamic storage
125 m_Storage.m_dynSet=new set_value_type[m_Size];
16
Memory is allocated
126 DestStorage=m_Storage.m_dynSet;
127 SrcStorage=Other.m_Storage.m_dynSet;
128 }
129
130 // Use fixed storage
131 ::std::memcpy(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size);
132 }
133
134 // Destructor
135 ~is_any_ofF()
136 {
137 if(!use_fixed_storage(m_Size) && m_Storage.m_dynSet!=0)
21
Potential memory leak
138 {
139 delete [] m_Storage.m_dynSet;
140 }
141 }
142
143 // Assignment
144 is_any_ofF& operator=(const is_any_ofF& Other)
145 {
146 // Handle self assignment
147 if(this==&Other) return *this;
148
149 // Prepare storage
150 const set_value_type* SrcStorage;
151 set_value_type* DestStorage;
152
153 if(use_fixed_storage(Other.m_Size))
154 {
155 // Use fixed storage
156 DestStorage=&m_Storage.m_fixSet[0];
157 SrcStorage=&Other.m_Storage.m_fixSet[0];
158
159 // Delete old storage if was present
160 if(!use_fixed_storage(m_Size) && m_Storage.m_dynSet!=0)
161 {
162 delete [] m_Storage.m_dynSet;
163 }
164
165 // Set new size
166 m_Size=Other.m_Size;
167 }
168 else
169 {
170 // Other uses dynamic storage
171 SrcStorage=Other.m_Storage.m_dynSet;
172
173 // Check what kind of storage are we using right now
174 if(use_fixed_storage(m_Size))
175 {
176 // Using fixed storage, allocate new
177 set_value_type* pTemp=new set_value_type[Other.m_Size];
178 DestStorage=pTemp;
179 m_Storage.m_dynSet=pTemp;
180 m_Size=Other.m_Size;
181 }
182 else
183 {
184 // Using dynamic storage, check if can reuse
185 if(m_Storage.m_dynSet!=0 && m_Size>=Other.m_Size && m_Size<Other.m_Size*2)
186 {
187 // Reuse the current storage
188 DestStorage=m_Storage.m_dynSet;
189 m_Size=Other.m_Size;
190 }
191 else
192 {
193 // Allocate the new one
194 set_value_type* pTemp=new set_value_type[Other.m_Size];
195 DestStorage=pTemp;
196
197 // Delete old storage if necessary
198 if(m_Storage.m_dynSet!=0)
199 {
200 delete [] m_Storage.m_dynSet;
201 }
202 // Store the new storage
203 m_Storage.m_dynSet=pTemp;
204 // Set new size
205 m_Size=Other.m_Size;
206 }
207 }
208 }
209
210 // Copy the data
211 ::std::memcpy(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size);
212
213 return *this;
214 }
215
216 // Operation
217 template<typename Char2T>
218 bool operator()( Char2T Ch ) const
219 {
220 const set_value_type* Storage=
221 (use_fixed_storage(m_Size))
222 ? &m_Storage.m_fixSet[0]
223 : m_Storage.m_dynSet;
224
225 return ::std::binary_search(Storage, Storage+m_Size, Ch);
226 }
227 private:
228 // check if the size is eligible for fixed storage
229 static bool use_fixed_storage(std::size_t size)
230 {
231 return size<=sizeof(set_value_type*)*2;
232 }
233
234
235 private:
236 // storage
237 // The actual used storage is selected on the type
238 union
239 {
240 set_value_type* m_dynSet;
241 set_value_type m_fixSet[sizeof(set_value_type*)*2];
242 }
243 m_Storage;
244
245 // storage size
246 ::std::size_t m_Size;
247 };
248
249 // is_from_range functor
250 /*
251 returns true if the value is from the specified range.
252 (i.e. x>=From && x>=To)
253 */
254 template<typename CharT>
255 struct is_from_rangeF :
256 public predicate_facade< is_from_rangeF<CharT> >
257 {
258 // Boost.ResultOf support
259 typedef bool result_type;
260
261 // Constructor
262 is_from_rangeF( CharT From, CharT To ) : m_From(From), m_To(To) {}
263
264 // Operation
265 template<typename Char2T>
266 bool operator()( Char2T Ch ) const
267 {
268 return ( m_From <= Ch ) && ( Ch <= m_To );
269 }
270
271 private:
272 CharT m_From;
273 CharT m_To;
274 };
275
276 // class_and composition predicate
277 template<typename Pred1T, typename Pred2T>
278 struct pred_andF :
279 public predicate_facade< pred_andF<Pred1T,Pred2T> >
280 {
281 public:
282
283 // Boost.ResultOf support
284 typedef bool result_type;
285
286 // Constructor
287 pred_andF( Pred1T Pred1, Pred2T Pred2 ) :
288 m_Pred1(Pred1), m_Pred2(Pred2) {}
289
290 // Operation
291 template<typename CharT>
292 bool operator()( CharT Ch ) const
293 {
294 return m_Pred1(Ch) && m_Pred2(Ch);
295 }
296
297 private:
298 Pred1T m_Pred1;
299 Pred2T m_Pred2;
300 };
301
302 // class_or composition predicate
303 template<typename Pred1T, typename Pred2T>
304 struct pred_orF :
305 public predicate_facade< pred_orF<Pred1T,Pred2T> >
306 {
307 public:
308 // Boost.ResultOf support
309 typedef bool result_type;
310
311 // Constructor
312 pred_orF( Pred1T Pred1, Pred2T Pred2 ) :
313 m_Pred1(Pred1), m_Pred2(Pred2) {}
314
315 // Operation
316 template<typename CharT>
317 bool operator()( CharT Ch ) const
318 {
319 return m_Pred1(Ch) || m_Pred2(Ch);
320 }
321
322 private:
323 Pred1T m_Pred1;
324 Pred2T m_Pred2;
325 };
326
327 // class_not composition predicate
328 template< typename PredT >
329 struct pred_notF :
330 public predicate_facade< pred_notF<PredT> >
331 {
332 public:
333 // Boost.ResultOf support
334 typedef bool result_type;
335
336 // Constructor
337 pred_notF( PredT Pred ) : m_Pred(Pred) {}
338
339 // Operation
340 template<typename CharT>
341 bool operator()( CharT Ch ) const
342 {
343 return !m_Pred(Ch);
344 }
345
346 private:
347 PredT m_Pred;
348 };
349
350 } // namespace detail
351 } // namespace algorithm
352} // namespace boost
353
354
355#endif // BOOST_STRING_CLASSIFICATION_DETAIL_HPP