Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/graph/detail/bitset.hpp @ 35

Last change on this file since 35 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 32.5 KB
Line 
1//=======================================================================
2// Copyright 2001 Jeremy G. Siek
3// Authors: Jeremy G. Siek
4//
5// Distributed under the Boost Software License, Version 1.0. (See
6// accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8//=======================================================================
9
10/*
11 * Copyright (c) 1998
12 * Silicon Graphics Computer Systems, Inc.
13 *
14 * Permission to use, copy, modify, distribute and sell this software
15 * and its documentation for any purpose is hereby granted without fee,
16 * provided that the above copyright notice appear in all copies and
17 * that both that copyright notice and this permission notice appear
18 * in supporting documentation.  Silicon Graphics makes no
19 * representations about the suitability of this software for any
20 * purpose.  It is provided "as is" without express or implied warranty.
21 */
22
23#include <boost/config.hpp>
24#include <memory>
25#include <stdexcept>
26#include <algorithm>
27#include <string>
28#include <boost/config.hpp>
29#include <boost/pending/ct_if.hpp>
30#include <boost/graph/detail/bitset_adaptor.hpp>
31
32// This provides versions of std::bitset with both static and dynamic size.
33
34// UNDER CONSTRUCTION
35
36
37// replace this later
38#include <cassert>
39#define BOOST_ASSERT_THROW(expr, except) assert(expr)
40
41namespace boost {
42
43  namespace detail {
44    // structure to aid in counting bits
45    template<bool dummy = true>
46    struct bit_count {
47      static unsigned char value[256];
48    };
49
50    // Mapping from 8 bit unsigned integers to the index of the first bit
51    template<bool dummy = true>
52    struct first_bit_location {
53      static unsigned char value[256];
54    };
55
56    template <typename WordType>  // this size is in bits
57    struct word_traits {
58      typedef WordType word_type;
59      static const std::size_t word_size = CHAR_BIT * sizeof(word_type);
60    };
61   
62    //=========================================================================
63    template <class WordTraits, class SizeType, class Derived>
64    class bitset_base
65      : public bitset_adaptor< SizeType, 
66                               bitset_base<WordTraits, SizeType, Derived> >
67    {
68      //    private:
69    public:
70      typedef SizeType size_type;
71      typedef typename WordTraits::word_type word_type;
72
73      static size_type s_which_word(size_type pos) {
74        return pos / WordTraits::word_size;
75      }
76      static size_type s_which_byte(size_type pos) {
77        return (pos % WordTraits::word_size) / CHAR_BIT;
78      }
79      static size_type s_which_bit(size_type pos) {
80        return pos % WordTraits::word_size;
81      }
82      static word_type s_mask_bit(size_type pos) {
83        return (static_cast<word_type>(1)) << s_which_bit(pos); 
84      }
85      word_type& m_get_word(size_type pos) {
86        return data()[s_which_word(pos)]; 
87      }
88      word_type m_get_word(size_type pos) const {
89        return data()[s_which_word(pos)]; 
90      }
91      word_type& m_hi_word() { return data()[num_words() - 1]; }
92      word_type  m_hi_word() const { return data()[num_words() - 1]; }
93
94      void m_sanitize_highest() {
95        size_type extra_bits = size() % WordTraits::word_size;
96        if (extra_bits)
97          m_hi_word() &= ~((~static_cast<word_type>(0)) << extra_bits);
98      }
99    public:
100
101      class reference {
102        friend class bitset_base;
103
104        word_type *m_word_ptr;
105        size_type m_bit_pos;
106
107        // left undefined
108        reference();
109
110        reference(bitset_base& b, size_type pos ) {
111          m_word_ptr = &b.m_get_word(pos);
112          m_bit_pos = s_which_bit(pos);
113        }
114
115      public:
116        ~reference() {}
117
118        // for b[i] = x;
119        reference& operator=(bool x) {
120          if ( x )
121            *m_word_ptr |= s_mask_bit(m_bit_pos);
122          else
123            *m_word_ptr &= ~s_mask_bit(m_bit_pos);
124
125          return *this;
126        }
127        // for b[i] = b[j];
128        reference& operator=(const reference& j) {
129          if ( (*(j.m_word_ptr) & s_mask_bit(j.m_bit_pos)) )
130            *m_word_ptr |= s_mask_bit(m_bit_pos);
131          else
132            *m_word_ptr &= ~s_mask_bit(m_bit_pos);
133
134          return *this;
135        }
136        // flips the bit
137        bool operator~() const { 
138          return (*(m_word_ptr) & s_mask_bit(m_bit_pos)) == 0; 
139        }
140        // for x = b[i];
141        operator bool() const { 
142          return (*(m_word_ptr) & s_mask_bit(m_bit_pos)) != 0; 
143        }
144        // for b[i].flip();
145        reference& flip() {
146          *m_word_ptr ^= s_mask_bit(m_bit_pos);
147          return *this;
148        }
149      };
150
151      void init_from_ulong(unsigned long val) {
152        reset();
153        const size_type n = (std::min)(sizeof(unsigned long) * CHAR_BIT,
154                                     WordTraits::word_size * num_words());
155        for(size_type i = 0; i < n; ++i, val >>= 1)
156          if ( val & 0x1 )
157            m_get_word(i) |= s_mask_bit(i);
158      }
159     
160      // intersection: this = this & x
161      Derived& operator&=(const Derived& x) {
162        for (size_type i = 0; i < num_words(); ++i)
163          data()[i] &= x.data()[i];
164        return static_cast<Derived&>(*this);
165      }
166      // union: this = this | x
167      Derived& operator|=(const Derived& x) {
168        for (size_type i = 0; i < num_words(); ++i)
169          data()[i] |= x.data()[i];
170        return static_cast<Derived&>(*this);
171      }
172      // exclusive or: this = this ^ x
173      Derived& operator^=(const Derived& x) {
174        for (size_type i = 0; i < num_words(); ++i)
175          data()[i] ^= x.data()[i];
176        return static_cast<Derived&>(*this);
177      }
178      // left shift
179      Derived& operator<<=(size_type pos);
180
181      // right shift
182      Derived& operator>>=(size_type pos);
183
184      Derived& set() {
185        for (size_type i = 0; i < num_words(); ++i)
186          data()[i] = ~static_cast<word_type>(0);
187        m_sanitize_highest();
188        return static_cast<Derived&>(*this);
189      }
190
191      Derived& set(size_type pos, int val = true)
192      {
193        BOOST_ASSERT_THROW(pos < size(), std::out_of_range("boost::bitset::set(pos,value)"));
194        if (val)
195          m_get_word(pos) |= s_mask_bit(pos);
196        else
197          m_get_word(pos) &= ~s_mask_bit(pos);
198        return static_cast<Derived&>(*this);
199      }
200     
201      Derived& reset() {
202        for (size_type i = 0; i < num_words(); ++i)
203          data()[i] = 0;
204        return static_cast<Derived&>(*this);
205      }
206
207      Derived& reset(size_type pos) {
208        BOOST_ASSERT_THROW(pos < size(), std::out_of_range("boost::bitset::reset(pos)"));
209        m_get_word(pos) &= ~s_mask_bit(pos);
210        return static_cast<Derived&>(*this);
211      }
212
213      // compliment
214      Derived operator~() const {
215        return Derived(static_cast<const Derived&>(*this)).flip();
216      }
217     
218      Derived& flip() {
219        for (size_type i = 0; i < num_words(); ++i)
220          data()[i] = ~data()[i];
221        m_sanitize_highest();
222        return static_cast<Derived&>(*this);
223      }
224      Derived& flip(size_type pos) {
225        BOOST_ASSERT_THROW(pos < size(), std::out_of_range("boost::bitset::flip(pos)"));
226        m_get_word(pos) ^= s_mask_bit(pos);
227        return static_cast<Derived&>(*this);
228      }
229
230      // element access
231      reference operator[](size_type pos) { return reference(*this, pos); }
232      bool operator[](size_type pos) const { return test(pos); }
233
234      unsigned long to_ulong() const;
235
236      // to_string
237
238     
239      size_type count() const {
240        size_type result = 0;
241        const unsigned char* byte_ptr = (const unsigned char*)data();
242        const unsigned char* end_ptr = 
243          (const unsigned char*)(data() + num_words());
244        while ( byte_ptr < end_ptr ) {
245          result += bit_count<>::value[*byte_ptr];
246          byte_ptr++;
247        }
248        return result;
249      }   
250     
251      // size() must be provided by Derived class
252
253      bool operator==(const Derived& x) const {
254        return std::equal(data(), data() + num_words(), x.data());
255      }
256
257      bool operator!=(const Derived& x) const {
258        return ! this->operator==(x);
259      }
260
261      bool test(size_type pos) const {
262        BOOST_ASSERT_THROW(pos < size(), std::out_of_range("boost::bitset::test(pos)"));
263        return (m_get_word(pos) & s_mask_bit(pos))
264          != static_cast<word_type>(0);
265      }
266
267      bool any() const {
268        for (size_type i = 0; i < num_words(); ++i) {
269          if ( data()[i] != static_cast<word_type>(0) )
270            return true;
271        }
272        return false;
273      }
274      bool none() const {
275        return !any();
276      }
277
278      Derived operator<<(size_type pos) const
279        { return Derived(static_cast<const Derived&>(*this)) <<= pos; }
280
281      Derived operator>>(size_type pos) const
282        { return Derived(static_cast<const Derived&>(*this)) >>= pos; }
283
284      template <class CharT, class Traits, class Alloc>
285      void m_copy_from_string(const basic_string<CharT,Traits,Alloc>& s,
286                              size_type pos, size_type n)
287      {
288        reset();
289        const size_type nbits = (std::min)(size(), (std::min)(n, s.size() - pos));
290        for (size_type i = 0; i < nbits; ++i) {
291          switch(s[pos + nbits - i - 1]) {
292          case '0':
293            break;
294          case '1':
295            this->set(i);
296            break;
297          default:
298            throw std::invalid_argument
299              ("boost::bitset_base::m_copy_from_string(s, pos, n)");
300          }
301        }
302      }
303
304      template <class CharT, class Traits, class Alloc>
305      void m_copy_to_string(basic_string<CharT, Traits, Alloc>& s) const
306      {
307        s.assign(size(), '0');
308       
309        for (size_type i = 0; i < size(); ++i)
310          if (test(i))
311            s[size() - 1 - i] = '1';
312      }
313
314      //-----------------------------------------------------------------------
315      // Stuff not in std::bitset
316
317      // difference:  this = this - x
318      Derived& operator-=(const Derived& x) {
319        for (size_type i = 0; i < num_words(); ++i)
320          data()[i] &= ~x.data()[i];
321        return static_cast<Derived&>(*this);
322      }
323
324      // this wasn't working, why?
325      int compare_3way(const Derived& x) const {
326        return std::lexicographical_compare_3way
327          (data(), data() + num_words(), x.data(), x.data() + x.num_words());
328      }
329
330      // less-than compare
331      bool operator<(const Derived& x) const {
332        return std::lexicographical_compare
333          (data(), data() + num_words(), x.data(), x.data() + x.num_words());
334      }
335
336      // find the index of the first "on" bit
337      size_type find_first() const;
338
339      // find the index of the next "on" bit after prev
340      size_type find_next(size_type prev) const;
341
342     
343      size_type _Find_first() const { return find_first(); }
344
345      // find the index of the next "on" bit after prev
346      size_type _Find_next(size_type prev) const { return find_next(prev); }
347
348      //    private:
349      word_type* data()
350        { return static_cast<Derived*>(this)->data(); }
351
352      const word_type* data() const 
353        { return static_cast<const Derived*>(this)->data(); }
354
355      size_type num_words() const 
356        { return static_cast<const Derived*>(this)->num_words(); }
357
358      size_type size() const 
359        { return static_cast<const Derived*>(this)->size(); }
360    };
361
362    // 23.3.5.3 bitset operations:
363    template <class W, class S, class D>
364    inline D operator&(const bitset_base<W,S,D>& x,
365                       const bitset_base<W,S,D>& y) {
366      D result(static_cast<const D&>(x));
367      result &= static_cast<const D&>(y);
368      return result;
369    }
370
371    template <class W, class S, class D>
372    inline D operator|(const bitset_base<W,S,D>& x,
373                       const bitset_base<W,S,D>& y) {
374      D result(static_cast<const D&>(x));
375      result |= static_cast<const D&>(y);
376      return result;
377    }
378
379    template <class W, class S, class D>
380    inline D operator^(const bitset_base<W,S,D>& x,
381                       const bitset_base<W,S,D>& y) {
382      D result(static_cast<const D&>(x));
383      result ^= static_cast<const D&>(y);
384      return result;
385    }
386
387    // this one is an extension
388    template <class W, class S, class D>
389    inline D operator-(const bitset_base<W,S,D>& x,
390                       const bitset_base<W,S,D>& y) {
391      D result(static_cast<const D&>(x));
392      result -= static_cast<const D&>(y);
393      return result;
394    }
395
396    template <class W, class S, class D>
397    inline int compare_3way(const bitset_base<W,S,D>& x,
398                            const bitset_base<W,S,D>& y) {
399      return std::lexicographical_compare_3way
400        (x.data(), x.data() + x.num_words(), 
401         y.data(), y.data() + y.num_words());
402    }
403
404
405    template <class W, class S, class D>
406    std::istream&
407    operator>>(std::istream& is, bitset_base<W,S,D>& x) {
408      std::string tmp;
409      tmp.reserve(x.size());
410
411      // In new templatized iostreams, use istream::sentry
412      if (is.flags() & ios::skipws) {
413        char c;
414        do
415          is.get(c);
416        while (is && isspace(c));
417        if (is)
418          is.putback(c);
419      }
420
421      for (S i = 0; i < x.size(); ++i) {
422        char c;
423        is.get(c);
424
425        if (!is)
426          break;
427        else if (c != '0' && c != '1') {
428          is.putback(c);
429          break;
430        }
431        else
432          //      tmp.push_back(c);
433          tmp += c;
434      }
435
436      if (tmp.empty())
437        is.clear(is.rdstate() | ios::failbit);
438      else
439        x.m_copy_from_string(tmp, static_cast<S>(0), x.size());
440
441      return is;
442    }
443
444    template <class W, class S, class D>
445    std::ostream& operator<<(std::ostream& os, 
446                             const bitset_base<W,S,D>& x) {
447      std::string tmp;
448      x.m_copy_to_string(tmp);
449      return os << tmp;
450    }
451
452    //=========================================================================
453    template <typename WordType = unsigned long,
454              typename SizeType = std::size_t,
455              typename Allocator = std::allocator<WordType>
456             >
457    class dyn_size_bitset
458      : public bitset_base<word_traits<WordType>, SizeType,
459          dyn_size_bitset<WordType,SizeType,Allocator> >
460    {
461      typedef dyn_size_bitset self;
462    public:
463      typedef SizeType size_type;
464    private:
465      typedef word_traits<WordType> WordTraits;
466      static const size_type word_size = WordTraits::word_size;
467
468    public:
469      dyn_size_bitset(unsigned long val, 
470                      size_type n,
471                      const Allocator& alloc = Allocator()) 
472        : m_data(alloc.allocate((n + word_size - 1) / word_size)),
473          m_size(n),
474          m_num_words((n + word_size - 1) / word_size),
475          m_alloc(alloc)
476      {
477        init_from_ulong(val);
478      }
479
480      dyn_size_bitset(size_type n,  // size of the set's "universe"
481                      const Allocator& alloc = Allocator())
482        : m_data(alloc.allocate((n + word_size - 1) / word_size)), 
483          m_size(n), m_num_words((n + word_size - 1) / word_size),
484          m_alloc(alloc)
485      { }
486
487      template<class CharT, class Traits, class Alloc>
488      explicit dyn_size_bitset
489        (const basic_string<CharT,Traits,Alloc>& s,
490         std::size_t pos = 0,
491         std::size_t n = std::size_t(basic_string<CharT,Traits,Alloc>::npos),
492         const Allocator& alloc = Allocator())
493        : m_data(alloc.allocate((n + word_size - 1) / word_size)), 
494          m_size(n), m_num_words((n + word_size - 1) / word_size),
495          m_alloc(alloc)
496      {
497        BOOST_ASSERT_THROW(pos < s.size(), std::out_of_range("dyn_size_bitset::dyn_size_bitset(s,pos,n,alloc)"));
498        m_copy_from_string(s, pos, n);
499      }
500
501      template <typename InputIterator>
502      explicit dyn_size_bitset
503        (InputIterator first, InputIterator last,
504         size_type n,  // size of the set's "universe"
505         const Allocator& alloc = Allocator())
506        : m_data(alloc.allocate((n + word_size - 1) / word_size)), 
507          m_size(N), m_num_words((n + word_size - 1) / word_size),
508          m_alloc(alloc)
509      {
510        while (first != last)
511          this->set(*first++);
512      }
513
514      ~dyn_size_bitset() { 
515        m_alloc.deallocate(m_data, m_num_words); 
516      }
517     
518      size_type size() const { return m_size; }
519
520      // protected:
521      size_type num_words() const { return m_num_words; }
522
523      word_type* data() { return m_data; }
524      const word_type* data() const { return m_data; }
525
526    protected:
527      word_type* m_data;
528      SizeType m_size;
529      SizeType m_num_words;
530      Allocator m_alloc;
531    };
532
533    //=========================================================================
534    template <std::size_t N, typename WordType = unsigned long,
535      typename SizeType = std::size_t>
536    class bitset
537      : public bitset_base<word_traits<WordType>, SizeType,
538          bitset<N, WordType, SizeType> >
539    {
540      typedef bitset self;
541      static const std::size_t word_size = word_traits<WordType>::word_size;
542    public:
543        // 23.3.5.1 constructors:
544      bitset() {
545#if defined(__GNUC__)
546        for (size_type i = 0; i < num_words(); ++i)
547          m_data[i] = static_cast<WordType>(0);
548#endif
549      }
550
551      bitset(unsigned long val) {
552        init_from_ulong(val);
553      }
554
555      template<class CharT, class Traits, class Alloc>
556      explicit bitset
557        (const basic_string<CharT,Traits,Alloc>& s,
558         std::size_t pos = 0,
559         std::size_t n = std::size_t(basic_string<CharT,Traits,Alloc>::npos))
560      {
561        BOOST_ASSERT_THROW
562          (pos < s.size(), std::out_of_range("bitset::bitset(s,pos,n)"));
563        m_copy_from_string(s, pos, n);
564      }
565
566      size_type size() const { return N; }
567
568      // protected:
569      size_type num_words() const { return (N + word_size - 1) / word_size; }
570
571      word_type* data() { return m_data; }
572      const word_type* data() const { return m_data; }
573    protected:
574      word_type m_data[(N + word_size - 1) / word_size];
575    };
576
577    //=========================================================================
578    struct select_static_bitset {
579      template <std::size_t N, typename WordT, typename SizeT, typename Alloc>
580      struct bind_ {
581        typedef bitset<N, WordT, SizeT> type;
582      };
583    };
584    struct select_dyn_size_bitset {
585      template <std::size_t N, typename WordT, typename SizeT, typename Alloc>
586      struct bind_ {
587        typedef dyn_size_bitset<WordT, SizeT, Alloc> type;
588      };
589    };
590
591    template <std::size_t N = 0, // 0 means use dynamic
592      typename WordType = unsigned long,
593      typename Size_type = std::size_t, 
594      typename Allocator = std::allocator<WordType>
595             >
596    class bitset_generator {
597      typedef typename ct_if<N, select_dyn_size_bitset,
598        select_static_bitset>::type selector;
599    public:
600      typedef typename selector
601        ::template bind_<N, WordType, SizeType, Allocator>::type type;
602    };
603
604
605    //=========================================================================
606    // bitset_base non-inline member function implementations
607
608    template <class WordTraits, class SizeType, class Derived>
609    Derived&
610    bitset_base<WordTraits, SizeType, Derived>::
611    operator<<=(size_type shift)
612    {
613      typedef typename WordTraits::word_type word_type;
614      typedef SizeType size_type;
615      if (shift != 0) {
616        const size_type wshift = shift / WordTraits::word_size;
617        const size_type offset = shift % WordTraits::word_size;
618        const size_type sub_offset = WordTraits::word_size - offset;
619        size_type n = num_words() - 1;
620        for ( ; n > wshift; --n)
621          data()[n] = (data()[n - wshift] << offset) |
622            (data()[n - wshift - 1] >> sub_offset);
623        if (n == wshift)
624          data()[n] = data()[0] << offset;
625        for (size_type n1 = 0; n1 < n; ++n1)
626          data()[n1] = static_cast<word_type>(0);
627      }
628      m_sanitize_highest();
629      return static_cast<Derived&>(*this);
630    } // end operator<<=
631
632
633    template <class WordTraits, class SizeType, class Derived>
634    Derived&
635    bitset_base<WordTraits, SizeType, Derived>::
636    operator>>=(size_type shift)
637    {
638      typedef typename WordTraits::word_type word_type;
639      typedef SizeType size_type;
640      if (shift != 0) {
641        const size_type wshift = shift / WordTraits::word_size;
642        const size_type offset = shift % WordTraits::word_size;
643        const size_type sub_offset = WordTraits::word_size - offset;
644        const size_type limit = num_words() - wshift - 1;
645        size_type n = 0;
646        for ( ; n < limit; ++n)
647          data()[n] = (data()[n + wshift] >> offset) |
648            (data()[n + wshift + 1] << sub_offset);
649        data()[limit] = data()[num_words()-1] >> offset;
650        for (size_type n1 = limit + 1; n1 < num_words(); ++n1)
651          data()[n1] = static_cast<word_type>(0);
652      }
653      m_sanitize_highest();
654      return static_cast<Derived&>(*this);
655    } // end operator>>=
656
657
658    template <class WordTraits, class SizeType, class Derived>
659    unsigned long bitset_base<WordTraits, SizeType, Derived>::
660    to_ulong() const 
661    {
662      typedef typename WordTraits::word_type word_type;
663      typedef SizeType size_type;
664      const std::overflow_error
665        overflow("boost::bit_set::operator unsigned long()");
666
667      if (sizeof(word_type) >= sizeof(unsigned long)) {
668        for (size_type i = 1; i < num_words(); ++i)
669          BOOST_ASSERT_THROW(! data()[i], overflow);
670       
671        const word_type mask
672          = static_cast<word_type>(static_cast<unsigned long>(-1));
673        BOOST_ASSERT_THROW(! (data()[0] & ~mask), overflow);
674       
675        return static_cast<unsigned long>(data()[0] & mask);
676      }
677      else { // sizeof(word_type) < sizeof(unsigned long).
678        const size_type nwords =
679          (sizeof(unsigned long) + sizeof(word_type) - 1) / sizeof(word_type);
680
681        size_type min_nwords = nwords;
682        if (num_words() > nwords) {
683          for (size_type i = nwords; i < num_words(); ++i)
684            BOOST_ASSERT_THROW(!data()[i], overflow);
685        }
686        else
687          min_nwords = num_words();
688
689        // If unsigned long is 8 bytes and word_type is 6 bytes, then
690        // an unsigned long consists of all of one word plus 2 bytes
691        // from another word.
692        const size_type part = sizeof(unsigned long) % sizeof(word_type);
693
694#if 0
695        // bug in here?
696        // >> to far?
697        BOOST_ASSERT_THROW((part != 0
698                            && nwords <= num_words()
699                            && (data()[min_nwords - 1] >>
700                                ((sizeof(word_type) - part) * CHAR_BIT)) != 0),
701                           overflow);
702#endif
703
704        unsigned long result = 0;
705        for (size_type i = 0; i < min_nwords; ++i) {
706          result |= static_cast<unsigned long>(
707             data()[i]) << (i * sizeof(word_type) * CHAR_BIT);
708        }
709        return result;
710      }
711    }// end operator unsigned long()
712
713
714    template <class WordTraits, class SizeType, class Derived>
715    SizeType bitset_base<WordTraits,SizeType,Derived>::
716    find_first() const
717    {
718      SizeType not_found = size();
719      for (size_type i = 0; i < num_words(); i++ ) {
720        word_type thisword = data()[i];
721        if ( thisword != static_cast<word_type>(0) ) {
722          // find byte within word
723          for ( std::size_t j = 0; j < sizeof(word_type); j++ ) {
724            unsigned char this_byte
725              = static_cast<unsigned char>(thisword & (~(unsigned char)0));
726            if ( this_byte )
727              return i * WordTraits::word_size + j * CHAR_BIT +
728                first_bit_location<>::value[this_byte];
729
730            thisword >>= CHAR_BIT;
731          }
732        }
733      }
734      // not found, so return an indication of failure.
735      return not_found;
736    }
737
738    template <class WordTraits, class SizeType, class Derived>
739    SizeType bitset_base<WordTraits, SizeType, Derived>::
740    bitset_base<WordTraits,SizeType,Derived>::
741    find_next(size_type prev) const
742    {
743      SizeType not_found = size();
744      // make bound inclusive
745      ++prev;
746
747      // check out of bounds
748      if ( prev >= num_words() * WordTraits::word_size )
749        return not_found;
750
751        // search first word
752      size_type i = s_which_word(prev);
753      word_type thisword = data()[i];
754
755        // mask off bits below bound
756      thisword &= (~static_cast<word_type>(0)) << s_which_bit(prev);
757
758      if ( thisword != static_cast<word_type>(0) ) {
759        // find byte within word
760        // get first byte into place
761        thisword >>= s_which_byte(prev) * CHAR_BIT;
762        for ( size_type j = s_which_byte(prev); j < sizeof(word_type); j++ ) {
763          unsigned char this_byte
764            = static_cast<unsigned char>(thisword & (~(unsigned char)0));
765          if ( this_byte )
766            return i * WordTraits::word_size + j * CHAR_BIT +
767              first_bit_location<>::value[this_byte];
768
769          thisword >>= CHAR_BIT;
770        }
771      }
772
773      // check subsequent words
774      i++;
775      for ( ; i < num_words(); i++ ) {
776        word_type thisword = data()[i];
777        if ( thisword != static_cast<word_type>(0) ) {
778          // find byte within word
779          for ( size_type j = 0; j < sizeof(word_type); j++ ) {
780            unsigned char this_byte
781              = static_cast<unsigned char>(thisword & (~(unsigned char)0));
782            if ( this_byte )
783              return i * WordTraits::word_size + j * CHAR_BIT +
784                first_bit_location<>::value[this_byte];
785
786            thisword >>= CHAR_BIT;
787          }
788        }
789      }
790
791      // not found, so return an indication of failure.
792      return not_found;
793    } // end find_next
794
795
796    template <bool dummy>
797    unsigned char bit_count<dummy>::value[] = {
798      0, /*   0 */ 1, /*   1 */ 1, /*   2 */ 2, /*   3 */ 1, /*   4 */
799      2, /*   5 */ 2, /*   6 */ 3, /*   7 */ 1, /*   8 */ 2, /*   9 */
800      2, /*  10 */ 3, /*  11 */ 2, /*  12 */ 3, /*  13 */ 3, /*  14 */
801      4, /*  15 */ 1, /*  16 */ 2, /*  17 */ 2, /*  18 */ 3, /*  19 */
802      2, /*  20 */ 3, /*  21 */ 3, /*  22 */ 4, /*  23 */ 2, /*  24 */
803      3, /*  25 */ 3, /*  26 */ 4, /*  27 */ 3, /*  28 */ 4, /*  29 */
804      4, /*  30 */ 5, /*  31 */ 1, /*  32 */ 2, /*  33 */ 2, /*  34 */
805      3, /*  35 */ 2, /*  36 */ 3, /*  37 */ 3, /*  38 */ 4, /*  39 */
806      2, /*  40 */ 3, /*  41 */ 3, /*  42 */ 4, /*  43 */ 3, /*  44 */
807      4, /*  45 */ 4, /*  46 */ 5, /*  47 */ 2, /*  48 */ 3, /*  49 */
808      3, /*  50 */ 4, /*  51 */ 3, /*  52 */ 4, /*  53 */ 4, /*  54 */
809      5, /*  55 */ 3, /*  56 */ 4, /*  57 */ 4, /*  58 */ 5, /*  59 */
810      4, /*  60 */ 5, /*  61 */ 5, /*  62 */ 6, /*  63 */ 1, /*  64 */
811      2, /*  65 */ 2, /*  66 */ 3, /*  67 */ 2, /*  68 */ 3, /*  69 */
812      3, /*  70 */ 4, /*  71 */ 2, /*  72 */ 3, /*  73 */ 3, /*  74 */
813      4, /*  75 */ 3, /*  76 */ 4, /*  77 */ 4, /*  78 */ 5, /*  79 */
814      2, /*  80 */ 3, /*  81 */ 3, /*  82 */ 4, /*  83 */ 3, /*  84 */
815      4, /*  85 */ 4, /*  86 */ 5, /*  87 */ 3, /*  88 */ 4, /*  89 */
816      4, /*  90 */ 5, /*  91 */ 4, /*  92 */ 5, /*  93 */ 5, /*  94 */
817      6, /*  95 */ 2, /*  96 */ 3, /*  97 */ 3, /*  98 */ 4, /*  99 */
818      3, /* 100 */ 4, /* 101 */ 4, /* 102 */ 5, /* 103 */ 3, /* 104 */
819      4, /* 105 */ 4, /* 106 */ 5, /* 107 */ 4, /* 108 */ 5, /* 109 */
820      5, /* 110 */ 6, /* 111 */ 3, /* 112 */ 4, /* 113 */ 4, /* 114 */
821      5, /* 115 */ 4, /* 116 */ 5, /* 117 */ 5, /* 118 */ 6, /* 119 */
822      4, /* 120 */ 5, /* 121 */ 5, /* 122 */ 6, /* 123 */ 5, /* 124 */
823      6, /* 125 */ 6, /* 126 */ 7, /* 127 */ 1, /* 128 */ 2, /* 129 */
824      2, /* 130 */ 3, /* 131 */ 2, /* 132 */ 3, /* 133 */ 3, /* 134 */
825      4, /* 135 */ 2, /* 136 */ 3, /* 137 */ 3, /* 138 */ 4, /* 139 */
826      3, /* 140 */ 4, /* 141 */ 4, /* 142 */ 5, /* 143 */ 2, /* 144 */
827      3, /* 145 */ 3, /* 146 */ 4, /* 147 */ 3, /* 148 */ 4, /* 149 */
828      4, /* 150 */ 5, /* 151 */ 3, /* 152 */ 4, /* 153 */ 4, /* 154 */
829      5, /* 155 */ 4, /* 156 */ 5, /* 157 */ 5, /* 158 */ 6, /* 159 */
830      2, /* 160 */ 3, /* 161 */ 3, /* 162 */ 4, /* 163 */ 3, /* 164 */
831      4, /* 165 */ 4, /* 166 */ 5, /* 167 */ 3, /* 168 */ 4, /* 169 */
832      4, /* 170 */ 5, /* 171 */ 4, /* 172 */ 5, /* 173 */ 5, /* 174 */
833      6, /* 175 */ 3, /* 176 */ 4, /* 177 */ 4, /* 178 */ 5, /* 179 */
834      4, /* 180 */ 5, /* 181 */ 5, /* 182 */ 6, /* 183 */ 4, /* 184 */
835      5, /* 185 */ 5, /* 186 */ 6, /* 187 */ 5, /* 188 */ 6, /* 189 */
836      6, /* 190 */ 7, /* 191 */ 2, /* 192 */ 3, /* 193 */ 3, /* 194 */
837      4, /* 195 */ 3, /* 196 */ 4, /* 197 */ 4, /* 198 */ 5, /* 199 */
838      3, /* 200 */ 4, /* 201 */ 4, /* 202 */ 5, /* 203 */ 4, /* 204 */
839      5, /* 205 */ 5, /* 206 */ 6, /* 207 */ 3, /* 208 */ 4, /* 209 */
840      4, /* 210 */ 5, /* 211 */ 4, /* 212 */ 5, /* 213 */ 5, /* 214 */
841      6, /* 215 */ 4, /* 216 */ 5, /* 217 */ 5, /* 218 */ 6, /* 219 */
842      5, /* 220 */ 6, /* 221 */ 6, /* 222 */ 7, /* 223 */ 3, /* 224 */
843      4, /* 225 */ 4, /* 226 */ 5, /* 227 */ 4, /* 228 */ 5, /* 229 */
844      5, /* 230 */ 6, /* 231 */ 4, /* 232 */ 5, /* 233 */ 5, /* 234 */
845      6, /* 235 */ 5, /* 236 */ 6, /* 237 */ 6, /* 238 */ 7, /* 239 */
846      4, /* 240 */ 5, /* 241 */ 5, /* 242 */ 6, /* 243 */ 5, /* 244 */
847      6, /* 245 */ 6, /* 246 */ 7, /* 247 */ 5, /* 248 */ 6, /* 249 */
848      6, /* 250 */ 7, /* 251 */ 6, /* 252 */ 7, /* 253 */ 7, /* 254 */
849      8  /* 255 */
850    }; // end _Bit_count
851
852    template <bool dummy>
853    unsigned char first_bit_location<dummy>::value[] = {
854      0, /*   0 */ 0, /*   1 */ 1, /*   2 */ 0, /*   3 */ 2, /*   4 */
855      0, /*   5 */ 1, /*   6 */ 0, /*   7 */ 3, /*   8 */ 0, /*   9 */
856      1, /*  10 */ 0, /*  11 */ 2, /*  12 */ 0, /*  13 */ 1, /*  14 */
857      0, /*  15 */ 4, /*  16 */ 0, /*  17 */ 1, /*  18 */ 0, /*  19 */
858      2, /*  20 */ 0, /*  21 */ 1, /*  22 */ 0, /*  23 */ 3, /*  24 */
859      0, /*  25 */ 1, /*  26 */ 0, /*  27 */ 2, /*  28 */ 0, /*  29 */
860      1, /*  30 */ 0, /*  31 */ 5, /*  32 */ 0, /*  33 */ 1, /*  34 */
861      0, /*  35 */ 2, /*  36 */ 0, /*  37 */ 1, /*  38 */ 0, /*  39 */
862      3, /*  40 */ 0, /*  41 */ 1, /*  42 */ 0, /*  43 */ 2, /*  44 */
863      0, /*  45 */ 1, /*  46 */ 0, /*  47 */ 4, /*  48 */ 0, /*  49 */
864      1, /*  50 */ 0, /*  51 */ 2, /*  52 */ 0, /*  53 */ 1, /*  54 */
865      0, /*  55 */ 3, /*  56 */ 0, /*  57 */ 1, /*  58 */ 0, /*  59 */
866      2, /*  60 */ 0, /*  61 */ 1, /*  62 */ 0, /*  63 */ 6, /*  64 */
867      0, /*  65 */ 1, /*  66 */ 0, /*  67 */ 2, /*  68 */ 0, /*  69 */
868      1, /*  70 */ 0, /*  71 */ 3, /*  72 */ 0, /*  73 */ 1, /*  74 */
869      0, /*  75 */ 2, /*  76 */ 0, /*  77 */ 1, /*  78 */ 0, /*  79 */
870      4, /*  80 */ 0, /*  81 */ 1, /*  82 */ 0, /*  83 */ 2, /*  84 */
871      0, /*  85 */ 1, /*  86 */ 0, /*  87 */ 3, /*  88 */ 0, /*  89 */
872      1, /*  90 */ 0, /*  91 */ 2, /*  92 */ 0, /*  93 */ 1, /*  94 */
873      0, /*  95 */ 5, /*  96 */ 0, /*  97 */ 1, /*  98 */ 0, /*  99 */
874      2, /* 100 */ 0, /* 101 */ 1, /* 102 */ 0, /* 103 */ 3, /* 104 */
875      0, /* 105 */ 1, /* 106 */ 0, /* 107 */ 2, /* 108 */ 0, /* 109 */
876      1, /* 110 */ 0, /* 111 */ 4, /* 112 */ 0, /* 113 */ 1, /* 114 */
877      0, /* 115 */ 2, /* 116 */ 0, /* 117 */ 1, /* 118 */ 0, /* 119 */
878      3, /* 120 */ 0, /* 121 */ 1, /* 122 */ 0, /* 123 */ 2, /* 124 */
879      0, /* 125 */ 1, /* 126 */ 0, /* 127 */ 7, /* 128 */ 0, /* 129 */
880      1, /* 130 */ 0, /* 131 */ 2, /* 132 */ 0, /* 133 */ 1, /* 134 */
881      0, /* 135 */ 3, /* 136 */ 0, /* 137 */ 1, /* 138 */ 0, /* 139 */
882      2, /* 140 */ 0, /* 141 */ 1, /* 142 */ 0, /* 143 */ 4, /* 144 */
883      0, /* 145 */ 1, /* 146 */ 0, /* 147 */ 2, /* 148 */ 0, /* 149 */
884      1, /* 150 */ 0, /* 151 */ 3, /* 152 */ 0, /* 153 */ 1, /* 154 */
885      0, /* 155 */ 2, /* 156 */ 0, /* 157 */ 1, /* 158 */ 0, /* 159 */
886      5, /* 160 */ 0, /* 161 */ 1, /* 162 */ 0, /* 163 */ 2, /* 164 */
887      0, /* 165 */ 1, /* 166 */ 0, /* 167 */ 3, /* 168 */ 0, /* 169 */
888      1, /* 170 */ 0, /* 171 */ 2, /* 172 */ 0, /* 173 */ 1, /* 174 */
889      0, /* 175 */ 4, /* 176 */ 0, /* 177 */ 1, /* 178 */ 0, /* 179 */
890      2, /* 180 */ 0, /* 181 */ 1, /* 182 */ 0, /* 183 */ 3, /* 184 */
891      0, /* 185 */ 1, /* 186 */ 0, /* 187 */ 2, /* 188 */ 0, /* 189 */
892      1, /* 190 */ 0, /* 191 */ 6, /* 192 */ 0, /* 193 */ 1, /* 194 */
893      0, /* 195 */ 2, /* 196 */ 0, /* 197 */ 1, /* 198 */ 0, /* 199 */
894      3, /* 200 */ 0, /* 201 */ 1, /* 202 */ 0, /* 203 */ 2, /* 204 */
895      0, /* 205 */ 1, /* 206 */ 0, /* 207 */ 4, /* 208 */ 0, /* 209 */
896      1, /* 210 */ 0, /* 211 */ 2, /* 212 */ 0, /* 213 */ 1, /* 214 */
897      0, /* 215 */ 3, /* 216 */ 0, /* 217 */ 1, /* 218 */ 0, /* 219 */
898      2, /* 220 */ 0, /* 221 */ 1, /* 222 */ 0, /* 223 */ 5, /* 224 */
899      0, /* 225 */ 1, /* 226 */ 0, /* 227 */ 2, /* 228 */ 0, /* 229 */
900      1, /* 230 */ 0, /* 231 */ 3, /* 232 */ 0, /* 233 */ 1, /* 234 */
901      0, /* 235 */ 2, /* 236 */ 0, /* 237 */ 1, /* 238 */ 0, /* 239 */
902      4, /* 240 */ 0, /* 241 */ 1, /* 242 */ 0, /* 243 */ 2, /* 244 */
903      0, /* 245 */ 1, /* 246 */ 0, /* 247 */ 3, /* 248 */ 0, /* 249 */
904      1, /* 250 */ 0, /* 251 */ 2, /* 252 */ 0, /* 253 */ 1, /* 254 */
905      0, /* 255 */
906    }; // end _First_one
907
908  } // namespace detail
909
910} // namespace boost
Note: See TracBrowser for help on using the repository browser.