PageRenderTime 34ms CodeModel.GetById 22ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/xpressive/detail/utility/hash_peek_bitset.hpp

http://hadesmem.googlecode.com/
C++ Header | 178 lines | 140 code | 25 blank | 13 comment | 22 complexity | c6da715a658cecc08f38a67f47736f9e MD5 | raw file
  1///////////////////////////////////////////////////////////////////////////////
  2// hash_peek_bitset.hpp
  3//
  4//  Copyright 2008 Eric Niebler. Distributed under the Boost
  5//  Software License, Version 1.0. (See accompanying file
  6//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7
  8#ifndef BOOST_XPRESSIVE_DETAIL_HASH_PEEK_BITSET_HPP_EAN_10_04_2005
  9#define BOOST_XPRESSIVE_DETAIL_HASH_PEEK_BITSET_HPP_EAN_10_04_2005
 10
 11// MS compatible compilers support #pragma once
 12#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 13# pragma once
 14# pragma warning(push)
 15# pragma warning(disable : 4100) // unreferenced formal parameter
 16# pragma warning(disable : 4127) // conditional expression constant
 17#endif
 18
 19#include <bitset>
 20#include <string> // for std::char_traits
 21#include <boost/xpressive/detail/utility/chset/basic_chset.ipp>
 22
 23namespace boost { namespace xpressive { namespace detail
 24{
 25
 26///////////////////////////////////////////////////////////////////////////////
 27// hash_peek_bitset
 28//
 29template<typename Char>
 30struct hash_peek_bitset
 31{
 32    typedef Char char_type;
 33    typedef typename std::char_traits<char_type>::int_type int_type;
 34
 35    hash_peek_bitset()
 36      : icase_(false)
 37      , bset_()
 38    {
 39    }
 40
 41    std::size_t count() const
 42    {
 43        return this->bset_.count();
 44    }
 45
 46    void set_all()
 47    {
 48        this->icase_ = false;
 49        this->bset_.set();
 50    }
 51
 52    template<typename Traits>
 53    void set_char(char_type ch, bool icase, Traits const &tr)
 54    {
 55        if(this->test_icase_(icase))
 56        {
 57            ch = icase ? tr.translate_nocase(ch) : tr.translate(ch);
 58            this->bset_.set(tr.hash(ch));
 59        }
 60    }
 61
 62    template<typename Traits>
 63    void set_range(char_type from, char_type to, bool no, bool icase, Traits const &tr)
 64    {
 65        int_type ifrom = std::char_traits<char_type>::to_int_type(from);
 66        int_type ito = std::char_traits<char_type>::to_int_type(to);
 67        BOOST_ASSERT(ifrom <= ito);
 68        // bound the computational complexity. BUGBUG could set the inverse range
 69        if(no || 256 < (ito - ifrom))
 70        {
 71            this->set_all();
 72        }
 73        else if(this->test_icase_(icase))
 74        {
 75            for(int_type i = ifrom; i <= ito; ++i)
 76            {
 77                char_type ch = std::char_traits<char_type>::to_char_type(i);
 78                ch = icase ? tr.translate_nocase(ch) : tr.translate(ch);
 79                this->bset_.set(tr.hash(ch));
 80            }
 81        }
 82    }
 83
 84    template<typename Traits>
 85    void set_class(typename Traits::char_class_type char_class, bool no, Traits const &tr)
 86    {
 87        if(1 != sizeof(char_type))
 88        {
 89            // wide character set, no efficient way of filling in the bitset, so set them all to 1
 90            this->set_all();
 91        }
 92        else
 93        {
 94            for(std::size_t i = 0; i <= UCHAR_MAX; ++i)
 95            {
 96                char_type ch = std::char_traits<char_type>::to_char_type(static_cast<int_type>(i));
 97                if(no != tr.isctype(ch, char_class))
 98                {
 99                    this->bset_.set(i);
100                }
101            }
102        }
103    }
104
105    void set_bitset(hash_peek_bitset<Char> const &that)
106    {
107        if(this->test_icase_(that.icase()))
108        {
109            this->bset_ |= that.bset_;
110        }
111    }
112
113    void set_charset(basic_chset_8bit<Char> const &that, bool icase)
114    {
115        if(this->test_icase_(icase))
116        {
117            this->bset_ |= that.base();
118        }
119    }
120
121    bool icase() const
122    {
123        return this->icase_;
124    }
125
126    template<typename Traits>
127    bool test(char_type ch, Traits const &tr) const
128    {
129        ch = this->icase_ ? tr.translate_nocase(ch) : tr.translate(ch);
130        return this->bset_.test(tr.hash(ch));
131    }
132
133    template<typename Traits>
134    bool test(char_type ch, Traits const &tr, mpl::false_) const
135    {
136        BOOST_ASSERT(!this->icase_);
137        return this->bset_.test(tr.hash(tr.translate(ch)));
138    }
139
140    template<typename Traits>
141    bool test(char_type ch, Traits const &tr, mpl::true_) const
142    {
143        BOOST_ASSERT(this->icase_);
144        return this->bset_.test(tr.hash(tr.translate_nocase(ch)));
145    }
146
147private:
148
149    // Make sure all sub-expressions being merged have the same case-sensitivity
150    bool test_icase_(bool icase)
151    {
152        std::size_t count = this->bset_.count();
153
154        if(256 == count)
155        {
156            return false; // all set already, nothing to do
157        }
158        else if(0 != count && this->icase_ != icase)
159        {
160            this->set_all(); // icase mismatch! set all and bail
161            return false;
162        }
163
164        this->icase_ = icase;
165        return true;
166    }
167
168    bool icase_;
169    std::bitset<256> bset_;
170};
171
172}}} // namespace boost::xpressive::detail
173
174#if defined(_MSC_VER) && (_MSC_VER >= 1020)
175# pragma warning(pop)
176#endif
177
178#endif