Chris@16
|
1 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 // algorithm.hpp
|
Chris@16
|
3 //
|
Chris@16
|
4 // Copyright 2008 Eric Niebler. Distributed under the Boost
|
Chris@16
|
5 // Software License, Version 1.0. (See accompanying file
|
Chris@16
|
6 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
7
|
Chris@16
|
8 #ifndef BOOST_XPRESSIVE_DETAIL_UTILITY_ALGORITHM_HPP_EAN_10_04_2005
|
Chris@16
|
9 #define BOOST_XPRESSIVE_DETAIL_UTILITY_ALGORITHM_HPP_EAN_10_04_2005
|
Chris@16
|
10
|
Chris@16
|
11 // MS compatible compilers support #pragma once
|
Chris@101
|
12 #if defined(_MSC_VER)
|
Chris@16
|
13 # pragma once
|
Chris@16
|
14 #endif
|
Chris@16
|
15
|
Chris@16
|
16 #include <string>
|
Chris@16
|
17 #include <climits>
|
Chris@16
|
18 #include <algorithm>
|
Chris@16
|
19 #include <boost/version.hpp>
|
Chris@16
|
20 #include <boost/range/end.hpp>
|
Chris@16
|
21 #include <boost/range/begin.hpp>
|
Chris@16
|
22 #include <boost/range/size.hpp>
|
Chris@16
|
23 #include <boost/range/value_type.hpp>
|
Chris@16
|
24 #include <boost/type_traits/remove_const.hpp>
|
Chris@16
|
25 #include <boost/iterator/iterator_traits.hpp>
|
Chris@16
|
26 #include <boost/xpressive/detail/utility/ignore_unused.hpp>
|
Chris@16
|
27
|
Chris@16
|
28 namespace boost { namespace xpressive { namespace detail
|
Chris@16
|
29 {
|
Chris@16
|
30
|
Chris@16
|
31 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
32 // any
|
Chris@16
|
33 //
|
Chris@16
|
34 template<typename InIter, typename Pred>
|
Chris@16
|
35 inline bool any(InIter begin, InIter end, Pred pred)
|
Chris@16
|
36 {
|
Chris@16
|
37 return end != std::find_if(begin, end, pred);
|
Chris@16
|
38 }
|
Chris@16
|
39
|
Chris@16
|
40 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
41 // find_nth_if
|
Chris@16
|
42 //
|
Chris@16
|
43 template<typename FwdIter, typename Diff, typename Pred>
|
Chris@16
|
44 FwdIter find_nth_if(FwdIter begin, FwdIter end, Diff count, Pred pred)
|
Chris@16
|
45 {
|
Chris@16
|
46 for(; begin != end; ++begin)
|
Chris@16
|
47 {
|
Chris@16
|
48 if(pred(*begin) && 0 == count--)
|
Chris@16
|
49 {
|
Chris@16
|
50 return begin;
|
Chris@16
|
51 }
|
Chris@16
|
52 }
|
Chris@16
|
53
|
Chris@16
|
54 return end;
|
Chris@16
|
55 }
|
Chris@16
|
56
|
Chris@16
|
57 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
58 // toi
|
Chris@16
|
59 //
|
Chris@16
|
60 template<typename InIter, typename Traits>
|
Chris@16
|
61 int toi(InIter &begin, InIter end, Traits const &tr, int radix = 10, int max = INT_MAX)
|
Chris@16
|
62 {
|
Chris@16
|
63 detail::ignore_unused(tr);
|
Chris@16
|
64 int i = 0, c = 0;
|
Chris@16
|
65 for(; begin != end && -1 != (c = tr.value(*begin, radix)); ++begin)
|
Chris@16
|
66 {
|
Chris@16
|
67 if(max < ((i *= radix) += c))
|
Chris@16
|
68 return i / radix;
|
Chris@16
|
69 }
|
Chris@16
|
70 return i;
|
Chris@16
|
71 }
|
Chris@16
|
72
|
Chris@16
|
73 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
74 // advance_to
|
Chris@16
|
75 //
|
Chris@16
|
76 template<typename BidiIter, typename Diff>
|
Chris@16
|
77 inline bool advance_to_impl(BidiIter & iter, Diff diff, BidiIter end, std::bidirectional_iterator_tag)
|
Chris@16
|
78 {
|
Chris@16
|
79 for(; 0 < diff && iter != end; --diff)
|
Chris@16
|
80 ++iter;
|
Chris@16
|
81 for(; 0 > diff && iter != end; ++diff)
|
Chris@16
|
82 --iter;
|
Chris@16
|
83 return 0 == diff;
|
Chris@16
|
84 }
|
Chris@16
|
85
|
Chris@16
|
86 template<typename RandIter, typename Diff>
|
Chris@16
|
87 inline bool advance_to_impl(RandIter & iter, Diff diff, RandIter end, std::random_access_iterator_tag)
|
Chris@16
|
88 {
|
Chris@16
|
89 if(0 < diff)
|
Chris@16
|
90 {
|
Chris@16
|
91 if((end - iter) < diff)
|
Chris@16
|
92 return false;
|
Chris@16
|
93 }
|
Chris@16
|
94 else if(0 > diff)
|
Chris@16
|
95 {
|
Chris@16
|
96 if((iter - end) < -diff)
|
Chris@16
|
97 return false;
|
Chris@16
|
98 }
|
Chris@16
|
99 iter += diff;
|
Chris@16
|
100 return true;
|
Chris@16
|
101 }
|
Chris@16
|
102
|
Chris@16
|
103 template<typename Iter, typename Diff>
|
Chris@16
|
104 inline bool advance_to(Iter & iter, Diff diff, Iter end)
|
Chris@16
|
105 {
|
Chris@16
|
106 return detail::advance_to_impl(iter, diff, end, typename iterator_category<Iter>::type());
|
Chris@16
|
107 }
|
Chris@16
|
108
|
Chris@16
|
109 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
110 // range_data
|
Chris@16
|
111 //
|
Chris@16
|
112 template<typename T>
|
Chris@16
|
113 struct range_data
|
Chris@16
|
114 : range_value<T>
|
Chris@16
|
115 {};
|
Chris@16
|
116
|
Chris@16
|
117 template<typename T>
|
Chris@16
|
118 struct range_data<T *>
|
Chris@16
|
119 : remove_const<T>
|
Chris@16
|
120 {};
|
Chris@16
|
121
|
Chris@16
|
122 template<typename T> std::ptrdiff_t is_null_terminated(T const &) { return 0; }
|
Chris@16
|
123 #if BOOST_VERSION >= 103500
|
Chris@16
|
124 inline std::ptrdiff_t is_null_terminated(char const *) { return 1; }
|
Chris@16
|
125 #ifndef BOOST_XPRESSIVE_NO_WREGEX
|
Chris@16
|
126 inline std::ptrdiff_t is_null_terminated(wchar_t const *) { return 1; }
|
Chris@16
|
127 #endif
|
Chris@16
|
128 #endif
|
Chris@16
|
129
|
Chris@16
|
130 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
131 // data_begin/data_end
|
Chris@16
|
132 //
|
Chris@16
|
133 template<typename Cont>
|
Chris@16
|
134 typename range_data<Cont>::type const *data_begin(Cont const &cont)
|
Chris@16
|
135 {
|
Chris@16
|
136 return &*boost::begin(cont);
|
Chris@16
|
137 }
|
Chris@16
|
138
|
Chris@16
|
139 template<typename Cont>
|
Chris@16
|
140 typename range_data<Cont>::type const *data_end(Cont const &cont)
|
Chris@16
|
141 {
|
Chris@16
|
142 return &*boost::begin(cont) + boost::size(cont) - is_null_terminated(cont);
|
Chris@16
|
143 }
|
Chris@16
|
144
|
Chris@16
|
145 template<typename Char, typename Traits, typename Alloc>
|
Chris@16
|
146 Char const *data_begin(std::basic_string<Char, Traits, Alloc> const &str)
|
Chris@16
|
147 {
|
Chris@16
|
148 return str.data();
|
Chris@16
|
149 }
|
Chris@16
|
150
|
Chris@16
|
151 template<typename Char, typename Traits, typename Alloc>
|
Chris@16
|
152 Char const *data_end(std::basic_string<Char, Traits, Alloc> const &str)
|
Chris@16
|
153 {
|
Chris@16
|
154 return str.data() + str.size();
|
Chris@16
|
155 }
|
Chris@16
|
156
|
Chris@16
|
157 template<typename Char>
|
Chris@16
|
158 Char const *data_begin(Char const *const &sz)
|
Chris@16
|
159 {
|
Chris@16
|
160 return sz;
|
Chris@16
|
161 }
|
Chris@16
|
162
|
Chris@16
|
163 template<typename Char>
|
Chris@16
|
164 Char const *data_end(Char const *const &sz)
|
Chris@16
|
165 {
|
Chris@16
|
166 Char const *tmp = sz;
|
Chris@16
|
167 for(; *tmp; ++tmp)
|
Chris@16
|
168 ;
|
Chris@16
|
169 return tmp;
|
Chris@16
|
170 }
|
Chris@16
|
171
|
Chris@16
|
172 }}}
|
Chris@16
|
173
|
Chris@16
|
174 #endif
|