Chris@16: /* Chris@16: Copyright (c) Marshall Clow 2010-2012. Chris@16: Chris@16: Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: For more information, see http://www.boost.org Chris@16: */ Chris@16: Chris@16: #ifndef BOOST_ALGORITHM_SEARCH_DETAIL_BM_TRAITS_HPP Chris@16: #define BOOST_ALGORITHM_SEARCH_DETAIL_BM_TRAITS_HPP Chris@16: Chris@16: #include // for CHAR_BIT Chris@16: #include Chris@16: #include // for std::iterator_traits Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@101: #ifdef BOOST_NO_CXX11_HDR_UNORDERED_MAP Chris@101: #include Chris@101: #else Chris@101: #include Chris@101: #endif Chris@16: Chris@16: #include Chris@16: Chris@16: namespace boost { namespace algorithm { namespace detail { Chris@16: Chris@16: // Chris@16: // Default implementations of the skip tables for B-M and B-M-H Chris@16: // Chris@16: template class skip_table; Chris@16: Chris@16: // General case for data searching other than bytes; use a map Chris@16: template Chris@16: class skip_table { Chris@16: private: Chris@101: #ifdef BOOST_NO_CXX11_HDR_UNORDERED_MAP Chris@101: typedef boost::unordered_map skip_map; Chris@101: #else Chris@101: typedef std::unordered_map skip_map; Chris@101: #endif Chris@16: const value_type k_default_value; Chris@16: skip_map skip_; Chris@16: Chris@16: public: Chris@16: skip_table ( std::size_t patSize, value_type default_value ) Chris@16: : k_default_value ( default_value ), skip_ ( patSize ) {} Chris@16: Chris@16: void insert ( key_type key, value_type val ) { Chris@16: skip_ [ key ] = val; // Would skip_.insert (val) be better here? Chris@16: } Chris@16: Chris@16: value_type operator [] ( key_type key ) const { Chris@16: typename skip_map::const_iterator it = skip_.find ( key ); Chris@16: return it == skip_.end () ? k_default_value : it->second; Chris@16: } Chris@16: Chris@16: void PrintSkipTable () const { Chris@16: std::cout << "BM(H) Skip Table :" << std::endl; Chris@16: for ( typename skip_map::const_iterator it = skip_.begin (); it != skip_.end (); ++it ) Chris@16: if ( it->second != k_default_value ) Chris@16: std::cout << " " << it->first << ": " << it->second << std::endl; Chris@16: std::cout << std::endl; Chris@16: } Chris@16: }; Chris@16: Chris@16: Chris@16: // Special case small numeric values; use an array Chris@16: template Chris@16: class skip_table { Chris@16: private: Chris@16: typedef typename boost::make_unsigned::type unsigned_key_type; Chris@16: typedef boost::array skip_map; Chris@16: skip_map skip_; Chris@16: const value_type k_default_value; Chris@16: public: Chris@16: skip_table ( std::size_t patSize, value_type default_value ) : k_default_value ( default_value ) { Chris@16: std::fill_n ( skip_.begin(), skip_.size(), default_value ); Chris@16: } Chris@16: Chris@16: void insert ( key_type key, value_type val ) { Chris@16: skip_ [ static_cast ( key ) ] = val; Chris@16: } Chris@16: Chris@16: value_type operator [] ( key_type key ) const { Chris@16: return skip_ [ static_cast ( key ) ]; Chris@16: } Chris@16: Chris@16: void PrintSkipTable () const { Chris@16: std::cout << "BM(H) Skip Table :" << std::endl; Chris@16: for ( typename skip_map::const_iterator it = skip_.begin (); it != skip_.end (); ++it ) Chris@16: if ( *it != k_default_value ) Chris@16: std::cout << " " << std::distance (skip_.begin (), it) << ": " << *it << std::endl; Chris@16: std::cout << std::endl; Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct BM_traits { Chris@16: typedef typename std::iterator_traits::difference_type value_type; Chris@16: typedef typename std::iterator_traits::value_type key_type; Chris@16: typedef boost::algorithm::detail::skip_table::value && (sizeof(key_type)==1)> skip_table_t; Chris@16: }; Chris@16: Chris@16: }}} // namespaces Chris@16: Chris@16: #endif // BOOST_ALGORITHM_SEARCH_DETAIL_BM_TRAITS_HPP