summaryrefslogtreecommitdiff
path: root/boost/xpressive/detail/utility/algorithm.hpp
blob: b72bb2a35b584593abc22c1e825e015852acc8f8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
///////////////////////////////////////////////////////////////////////////////
// algorithm.hpp
//
//  Copyright 2008 Eric Niebler. Distributed under the Boost
//  Software License, Version 1.0. (See accompanying file
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_XPRESSIVE_DETAIL_UTILITY_ALGORITHM_HPP_EAN_10_04_2005
#define BOOST_XPRESSIVE_DETAIL_UTILITY_ALGORITHM_HPP_EAN_10_04_2005

// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif

#include <string>
#include <climits>
#include <algorithm>
#include <boost/version.hpp>
#include <boost/range/end.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/size.hpp>
#include <boost/range/value_type.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/xpressive/detail/utility/ignore_unused.hpp>

namespace boost { namespace xpressive { namespace detail
{

///////////////////////////////////////////////////////////////////////////////
// any
//
template<typename InIter, typename Pred>
inline bool any(InIter begin, InIter end, Pred pred)
{
    return end != std::find_if(begin, end, pred);
}

///////////////////////////////////////////////////////////////////////////////
// find_nth_if
//
template<typename FwdIter, typename Diff, typename Pred>
FwdIter find_nth_if(FwdIter begin, FwdIter end, Diff count, Pred pred)
{
    for(; begin != end; ++begin)
    {
        if(pred(*begin) && 0 == count--)
        {
            return begin;
        }
    }

    return end;
}

///////////////////////////////////////////////////////////////////////////////
// toi
//
template<typename InIter, typename Traits>
int toi(InIter &begin, InIter end, Traits const &tr, int radix = 10, int max = INT_MAX)
{
    detail::ignore_unused(tr);
    int i = 0, c = 0;
    for(; begin != end && -1 != (c = tr.value(*begin, radix)); ++begin)
    {
        if(max < ((i *= radix) += c))
            return i / radix;
    }
    return i;
}

///////////////////////////////////////////////////////////////////////////////
// advance_to
//
template<typename BidiIter, typename Diff>
inline bool advance_to_impl(BidiIter & iter, Diff diff, BidiIter end, std::bidirectional_iterator_tag)
{
    for(; 0 < diff && iter != end; --diff)
        ++iter;
    for(; 0 > diff && iter != end; ++diff)
        --iter;
    return 0 == diff;
}

template<typename RandIter, typename Diff>
inline bool advance_to_impl(RandIter & iter, Diff diff, RandIter end, std::random_access_iterator_tag)
{
    if(0 < diff)
    {
        if((end - iter) < diff)
            return false;
    }
    else if(0 > diff)
    {
        if((iter - end) < -diff)
            return false;
    }
    iter += diff;
    return true;
}

template<typename Iter, typename Diff>
inline bool advance_to(Iter & iter, Diff diff, Iter end)
{
    return detail::advance_to_impl(iter, diff, end, typename iterator_category<Iter>::type());
}

///////////////////////////////////////////////////////////////////////////////
// range_data
//
template<typename T>
struct range_data
  : range_value<T>
{};

template<typename T>
struct range_data<T *>
  : remove_const<T>
{};

template<typename T> std::ptrdiff_t is_null_terminated(T const &) { return 0; }
#if BOOST_VERSION >= 103500
inline std::ptrdiff_t is_null_terminated(char const *) { return 1; }
#ifndef BOOST_XPRESSIVE_NO_WREGEX
inline std::ptrdiff_t is_null_terminated(wchar_t const *) { return 1; }
#endif
#endif

///////////////////////////////////////////////////////////////////////////////
// data_begin/data_end
//
template<typename Cont>
typename range_data<Cont>::type const *data_begin(Cont const &cont)
{
    return &*boost::begin(cont);
}

template<typename Cont>
typename range_data<Cont>::type const *data_end(Cont const &cont)
{
    return &*boost::begin(cont) + boost::size(cont) - is_null_terminated(cont);
}

template<typename Char, typename Traits, typename Alloc>
Char const *data_begin(std::basic_string<Char, Traits, Alloc> const &str)
{
    return str.data();
}

template<typename Char, typename Traits, typename Alloc>
Char const *data_end(std::basic_string<Char, Traits, Alloc> const &str)
{
    return str.data() + str.size();
}

template<typename Char>
Char const *data_begin(Char const *const &sz)
{
    return sz;
}

template<typename Char>
Char const *data_end(Char const *const &sz)
{
    Char const *tmp = sz;
    for(; *tmp; ++tmp)
        ;
    return tmp;
}

}}}

#endif