bm_traits.hpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. Copyright (c) Marshall Clow 2010-2012.
  3. Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. For more information, see http://www.boost.org
  6. */
  7. #ifndef BOOST_ALGORITHM_SEARCH_DETAIL_BM_TRAITS_HPP
  8. #define BOOST_ALGORITHM_SEARCH_DETAIL_BM_TRAITS_HPP
  9. #include <climits> // for CHAR_BIT
  10. #include <vector>
  11. #include <iterator> // for std::iterator_traits
  12. #include <boost/type_traits/make_unsigned.hpp>
  13. #include <boost/type_traits/is_integral.hpp>
  14. #include <boost/type_traits/remove_pointer.hpp>
  15. #include <boost/type_traits/remove_const.hpp>
  16. #include <boost/array.hpp>
  17. #ifdef BOOST_NO_CXX11_HDR_UNORDERED_MAP
  18. #include <boost/unordered_map.hpp>
  19. #else
  20. #include <unordered_map>
  21. #endif
  22. #include <boost/algorithm/searching/detail/debugging.hpp>
  23. namespace boost { namespace algorithm { namespace detail {
  24. //
  25. // Default implementations of the skip tables for B-M and B-M-H
  26. //
  27. template<typename key_type, typename value_type, bool /*useArray*/> class skip_table;
  28. // General case for data searching other than bytes; use a map
  29. template<typename key_type, typename value_type>
  30. class skip_table<key_type, value_type, false> {
  31. private:
  32. #ifdef BOOST_NO_CXX11_HDR_UNORDERED_MAP
  33. typedef boost::unordered_map<key_type, value_type> skip_map;
  34. #else
  35. typedef std::unordered_map<key_type, value_type> skip_map;
  36. #endif
  37. const value_type k_default_value;
  38. skip_map skip_;
  39. public:
  40. skip_table ( std::size_t patSize, value_type default_value )
  41. : k_default_value ( default_value ), skip_ ( patSize ) {}
  42. void insert ( key_type key, value_type val ) {
  43. skip_ [ key ] = val; // Would skip_.insert (val) be better here?
  44. }
  45. value_type operator [] ( key_type key ) const {
  46. typename skip_map::const_iterator it = skip_.find ( key );
  47. return it == skip_.end () ? k_default_value : it->second;
  48. }
  49. void PrintSkipTable () const {
  50. std::cout << "BM(H) Skip Table <unordered_map>:" << std::endl;
  51. for ( typename skip_map::const_iterator it = skip_.begin (); it != skip_.end (); ++it )
  52. if ( it->second != k_default_value )
  53. std::cout << " " << it->first << ": " << it->second << std::endl;
  54. std::cout << std::endl;
  55. }
  56. };
  57. // Special case small numeric values; use an array
  58. template<typename key_type, typename value_type>
  59. class skip_table<key_type, value_type, true> {
  60. private:
  61. typedef typename boost::make_unsigned<key_type>::type unsigned_key_type;
  62. typedef boost::array<value_type, 1U << (CHAR_BIT * sizeof(key_type))> skip_map;
  63. skip_map skip_;
  64. const value_type k_default_value;
  65. public:
  66. skip_table ( std::size_t /*patSize*/, value_type default_value ) : k_default_value ( default_value ) {
  67. std::fill_n ( skip_.begin(), skip_.size(), default_value );
  68. }
  69. void insert ( key_type key, value_type val ) {
  70. skip_ [ static_cast<unsigned_key_type> ( key ) ] = val;
  71. }
  72. value_type operator [] ( key_type key ) const {
  73. return skip_ [ static_cast<unsigned_key_type> ( key ) ];
  74. }
  75. void PrintSkipTable () const {
  76. std::cout << "BM(H) Skip Table <boost:array>:" << std::endl;
  77. for ( typename skip_map::const_iterator it = skip_.begin (); it != skip_.end (); ++it )
  78. if ( *it != k_default_value )
  79. std::cout << " " << std::distance (skip_.begin (), it) << ": " << *it << std::endl;
  80. std::cout << std::endl;
  81. }
  82. };
  83. template<typename Iterator>
  84. struct BM_traits {
  85. typedef typename std::iterator_traits<Iterator>::difference_type value_type;
  86. typedef typename std::iterator_traits<Iterator>::value_type key_type;
  87. typedef boost::algorithm::detail::skip_table<key_type, value_type,
  88. boost::is_integral<key_type>::value && (sizeof(key_type)==1)> skip_table_t;
  89. };
  90. }}} // namespaces
  91. #endif // BOOST_ALGORITHM_SEARCH_DETAIL_BM_TRAITS_HPP