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