PageRenderTime 44ms CodeModel.GetById 13ms app.highlight 26ms RepoModel.GetById 1ms app.codeStats 0ms

/src/contrib/boost/spirit/home/support/char_set/range_run_impl.hpp

http://pythonocc.googlecode.com/
C++ Header | 189 lines | 133 code | 23 blank | 33 comment | 31 complexity | 6d463b963d489acc89097f8e0c15eace MD5 | raw file
  1/*=============================================================================
  2    Copyright (c) 2001-2010 Joel de Guzman
  3
  4    Distributed under the Boost Software License, Version 1.0. (See accompanying
  5    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6==============================================================================*/
  7#if !defined(BOOST_SPIRIT_RANGE_RUN_MAY_16_2006_0807_PM)
  8#define BOOST_SPIRIT_RANGE_RUN_MAY_16_2006_0807_PM
  9
 10#if defined(_MSC_VER)
 11#pragma once
 12#endif
 13
 14#include <boost/spirit/home/support/char_set/range_functions.hpp>
 15#include <boost/assert.hpp>
 16#include <boost/integer_traits.hpp>
 17#include <algorithm>
 18
 19namespace boost { namespace spirit { namespace support { namespace detail
 20{
 21    template <typename Run, typename Iterator, typename Range>
 22    inline bool
 23    try_merge(Run& run, Iterator iter, Range const& range)
 24    {
 25        // if *iter intersects with, or is adjacent to, 'range'...
 26        if (can_merge(*iter, range))
 27        {
 28            typedef typename Range::value_type value_type;
 29            typedef integer_traits<value_type> integer_traits;
 30
 31            // merge range and *iter
 32            merge(*iter, range);
 33
 34            // collapse all subsequent ranges that can merge with *iter:
 35            Iterator i = iter+1;
 36            // 1. skip subsequent ranges completely included in *iter
 37            while (i != run.end() && i->last <= iter->last)
 38                ++i;
 39            // 2. collapse next range if adjacent or overlapping with *iter
 40            if (i != run.end() && i->first-1 <= iter->last)
 41            {
 42                iter->last = i->last;
 43                ++i;
 44            }
 45
 46            // erase all ranges that were collapsed
 47            run.erase(iter+1, i);
 48            return true;
 49        }
 50        return false;
 51    }
 52
 53    template <typename Char>
 54    inline bool
 55    range_run<Char>::test(Char val) const
 56    {
 57        if (run.empty())
 58            return false;
 59
 60        // search the ranges for one that potentially includes val
 61        typename storage_type::const_iterator iter =
 62            std::upper_bound(
 63                run.begin(), run.end(), val,
 64                range_compare<range_type>()
 65            );
 66
 67        // return true if *(iter-1) includes val
 68        return iter != run.begin() && includes(*(--iter), val);
 69    }
 70
 71    template <typename Char>
 72    inline void
 73    range_run<Char>::swap(range_run& other)
 74    {
 75        run.swap(other.run);
 76    }
 77
 78    template <typename Char>
 79    void
 80    range_run<Char>::set(range_type const& range)
 81    {
 82        BOOST_ASSERT(is_valid(range));
 83        if (run.empty())
 84        {
 85            // the vector is empty, insert 'range'
 86            run.push_back(range);
 87            return;
 88        }
 89
 90        // search the ranges for one that potentially includes 'range'
 91        typename storage_type::iterator iter =
 92            std::upper_bound(
 93                run.begin(), run.end(), range,
 94                range_compare<range_type>()
 95            );
 96
 97        if (iter != run.begin())
 98        {
 99            // if *(iter-1) includes 'range', return early
100            if (includes(*(iter-1), range))
101            {
102                return;
103            }
104
105            // if *(iter-1) can merge with 'range', merge them and return
106            if (try_merge(run, iter-1, range))
107            {
108                return;
109            }
110        }
111
112        // if *iter can merge with with 'range', merge them
113        if (iter == run.end() || !try_merge(run, iter, range))
114        {
115            // no overlap, insert 'range'
116            run.insert(iter, range);
117        }
118    }
119
120    template <typename Char>
121    void
122    range_run<Char>::clear(range_type const& range)
123    {
124        BOOST_ASSERT(is_valid(range));
125        if (!run.empty())
126        {
127            // search the ranges for one that potentially includes 'range'
128            typename storage_type::iterator iter =
129                std::upper_bound(
130                    run.begin(), run.end(), range,
131                    range_compare<range_type>()
132                );
133
134            // 'range' starts with or after another range:
135            if (iter != run.begin())
136            {
137                typename storage_type::iterator const left_iter = iter-1;
138
139                // 'range' starts after '*left_iter':
140                if (left_iter->first < range.first)
141                {
142                    // if 'range' is completely included inside '*left_iter':
143                    // need to break it apart into two ranges (punch a hole),
144                    if (left_iter->last > range.last)
145                    {
146                        Char save_last = left_iter->last;
147                        left_iter->last = range.first-1;
148                        run.insert(iter, range_type(range.last+1, save_last));
149                        return;
150                    }
151                    // if 'range' contains 'left_iter->last':
152                    // truncate '*left_iter' (clip its right)
153                    else if (left_iter->last >= range.first)
154                    {
155                        left_iter->last = range.first-1;
156                    }
157                }
158
159                // 'range' has the same left bound as '*left_iter': it
160                // must be removed or truncated by the code below
161                else
162                {
163                    iter = left_iter;
164                }
165            }
166
167            // remove or truncate subsequent ranges that overlap with 'range':
168            typename storage_type::iterator i = iter;
169            // 1. skip subsequent ranges completely included in 'range'
170            while (i != run.end() && i->last <= range.last)
171                ++i;
172            // 2. clip left of next range if overlapping with 'range'
173            if (i != run.end() && i->first <= range.last)
174                i->first = range.last+1;
175
176            // erase all ranges that 'range' contained
177            run.erase(iter, i);
178        }
179    }
180
181    template <typename Char>
182    inline void
183    range_run<Char>::clear()
184    {
185        run.clear();
186    }
187}}}}
188
189#endif