dynamic_bitset.hpp
Go to the documentation of this file.
00001 // -----------------------------------------------------------
00002 //
00003 //   Copyright (c) 2001-2002 Chuck Allison and Jeremy Siek
00004 //        Copyright (c) 2003-2006, 2008 Gennaro Prota
00005 //
00006 // Distributed under the Boost Software License, Version 1.0.
00007 //    (See accompanying file LICENSE_1_0.txt or copy at
00008 //          http://www.boost.org/LICENSE_1_0.txt)
00009 //
00010 // -----------------------------------------------------------
00011 
00012 #ifndef BOOST_DETAIL_DYNAMIC_BITSET_HPP
00013 #define BOOST_DETAIL_DYNAMIC_BITSET_HPP
00014 
00015 #include <cstddef>
00016 #include "boost/config.hpp"
00017 #include "boost/detail/workaround.hpp"
00018 
00019 
00020 namespace boost {
00021 
00022   namespace detail {
00023   namespace dynamic_bitset_impl {
00024 
00025     // Gives (read-)access to the object representation
00026     // of an object of type T (3.9p4). CANNOT be used
00027     // on a base sub-object
00028     //
00029     template <typename T>
00030     inline const unsigned char * object_representation (T* p)
00031     {
00032         return static_cast<const unsigned char *>(static_cast<const void *>(p));
00033     }
00034 
00035     template<typename T, int amount, int width /* = default */>
00036     struct shifter
00037     {
00038         static void left_shift(T & v) {
00039             amount >= width ? (v = 0)
00040                 : (v >>= BOOST_DYNAMIC_BITSET_WRAP_CONSTANT(amount));
00041         }
00042     };
00043 
00044     // ------- count function implementation --------------
00045 
00046     typedef unsigned char byte_type;
00047 
00048     // These two entities
00049     //
00050     //     enum mode { access_by_bytes, access_by_blocks };
00051     //     template <mode> struct mode_to_type {};
00052     //
00053     // were removed, since the regression logs (as of 24 Aug 2008)
00054     // showed that several compilers had troubles with recognizing
00055     //
00056     //   const mode m = access_by_bytes
00057     //
00058     // as a constant expression
00059     //
00060     // * So, we'll use bool, instead of enum *.
00061     //
00062     template <bool value>
00063     struct value_to_type
00064     {
00065         value_to_type() {}
00066     };
00067     const bool access_by_bytes = true;
00068     const bool access_by_blocks = false;
00069 
00070 
00071     // the table: wrapped in a class template, so
00072     // that it is only instantiated if/when needed
00073     //
00074     template <bool dummy_name = true>
00075     struct count_table { static const byte_type table[]; };
00076 
00077     template <>
00078     struct count_table<false> { /* no table */ };
00079 
00080 
00081      const unsigned int table_width = 8;
00082      template <bool b>
00083      const byte_type count_table<b>::table[] =
00084      {
00085        // Automatically generated by GPTableGen.exe v.1.0
00086        //
00087      0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
00088      1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00089      1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00090      2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
00091      1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00092      2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
00093      2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
00094      3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
00095      };
00096 
00097 
00098      // overload for access by bytes
00099      //
00100 
00101      template <typename Iterator>
00102      inline std::size_t do_count(Iterator first, std::size_t length,
00103                                  int /*dummy param*/,
00104                                  value_to_type<access_by_bytes>* )
00105      {
00106          std::size_t num = 0;
00107          if (length)
00108          {
00109              const byte_type * p = object_representation(&*first);
00110              length *= sizeof(*first);
00111 
00112               do {
00113                  num += count_table<>::table[*p];
00114                  ++p;
00115                  --length;
00116 
00117              } while (length);
00118          }
00119 
00120          return num;
00121      }
00122 
00123 
00124      // overload for access by blocks
00125      //
00126      template <typename Iterator, typename ValueType>
00127      inline std::size_t do_count(Iterator first, std::size_t length, ValueType,
00128                                  value_to_type<access_by_blocks>*)
00129      {
00130          std::size_t num = 0;
00131          while (length){
00132 
00133              ValueType value = *first;
00134              while (value) {
00135                  num += count_table<>::table[value & ((1u<<table_width) - 1)];
00136                  value >>= table_width;
00137              }
00138 
00139              ++first;
00140              --length;
00141          }
00142 
00143          return num;
00144      }
00145 
00146     // -------------------------------------------------------
00147 
00148 
00149     // Some library implementations simply return a dummy
00150     // value such as
00151     //
00152     //   size_type(-1) / sizeof(T)
00153     //
00154     // from vector<>::max_size. This tries to get more
00155     // meaningful info.
00156     //
00157     template <typename T>
00158     typename T::size_type vector_max_size_workaround(const T & v) {
00159 
00160       typedef typename T::allocator_type allocator_type;
00161 
00162       const typename allocator_type::size_type alloc_max =
00163                                                   v.get_allocator().max_size();
00164       const typename T::size_type container_max = v.max_size();
00165 
00166       return alloc_max < container_max?
00167                     alloc_max :
00168                     container_max;
00169     }
00170 
00171     // for static_asserts
00172     template <typename T>
00173     struct allowed_block_type {
00174         enum { value = T(-1) > 0 }; // ensure T has no sign
00175     };
00176 
00177     template <>
00178     struct allowed_block_type<bool> {
00179         enum { value = false };
00180     };
00181 
00182 
00183     template <typename T>
00184     struct is_numeric {
00185         enum { value = false };
00186     };
00187 
00188 #   define BOOST_dynamic_bitset_is_numeric(x)       \
00189                 template<>                          \
00190                 struct is_numeric< x > {            \
00191                     enum { value = true };          \
00192                 }                                
00193 
00194     BOOST_dynamic_bitset_is_numeric(bool);
00195     BOOST_dynamic_bitset_is_numeric(char);
00196 
00197 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
00198     BOOST_dynamic_bitset_is_numeric(wchar_t);
00199 #endif
00200 
00201     BOOST_dynamic_bitset_is_numeric(signed char);
00202     BOOST_dynamic_bitset_is_numeric(short int);
00203     BOOST_dynamic_bitset_is_numeric(int);
00204     BOOST_dynamic_bitset_is_numeric(long int);
00205 
00206     BOOST_dynamic_bitset_is_numeric(unsigned char);
00207     BOOST_dynamic_bitset_is_numeric(unsigned short);
00208     BOOST_dynamic_bitset_is_numeric(unsigned int);
00209     BOOST_dynamic_bitset_is_numeric(unsigned long);
00210 
00211 #if defined(BOOST_HAS_LONG_LONG)
00212     BOOST_dynamic_bitset_is_numeric(::boost::long_long_type);
00213     BOOST_dynamic_bitset_is_numeric(::boost::ulong_long_type);
00214 #endif
00215 
00216     // intentionally omitted
00217     //BOOST_dynamic_bitset_is_numeric(float);
00218     //BOOST_dynamic_bitset_is_numeric(double);
00219     //BOOST_dynamic_bitset_is_numeric(long double);
00220 
00221 #undef BOOST_dynamic_bitset_is_numeric
00222 
00223   } // dynamic_bitset_impl
00224   } // namespace detail
00225 
00226 } // namespace boost
00227 
00228 #endif // include guard
00229 


appl
Author(s): petercai
autogenerated on Tue Jan 7 2014 11:02:29