// Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard. // Copyright (C) 2005-2011 Daniel James // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_UNORDERED_DETAIL_UTIL_HPP_INCLUDED #define BOOST_UNORDERED_DETAIL_UTIL_HPP_INCLUDED #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Template parameters: // // H = Hash Function // P = Predicate // A = Value Allocator // G = Bucket group policy, 'grouped' or 'ungrouped' // E = Key Extractor #if !defined(BOOST_NO_RVALUE_REFERENCES) && \ !defined(BOOST_NO_VARIADIC_TEMPLATES) # if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) # elif defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER) # elif defined(_LIBCPP_VERSION) # define BOOST_UNORDERED_STD_FORWARD_MOVE # elif defined(__GLIBCPP__) || defined(__GLIBCXX__) # if defined(__GLIBCXX__) && __GLIBCXX__ >= 20090804 # define BOOST_UNORDERED_STD_FORWARD_MOVE # endif # elif defined(__STL_CONFIG_H) # elif defined(__MSL_CPP__) # elif defined(__IBMCPP__) # elif defined(MSIPL_COMPILE_H) # elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER) // Visual C++. A version check would be a good idea. # define BOOST_UNORDERED_STD_FORWARD_MOVE # endif #endif #if !defined(BOOST_UNORDERED_EMPLACE_LIMIT) #define BOOST_UNORDERED_EMPLACE_LIMIT 10 #endif #if defined(__SUNPRO_CC) #define BOOST_UNORDERED_USE_RV_REF 0 #else #define BOOST_UNORDERED_USE_RV_REF 1 #endif #if !defined(BOOST_UNORDERED_STD_FORWARD_MOVE) #include #include #include #define BOOST_UNORDERED_TEMPLATE_ARGS(z, num_params) \ BOOST_PP_ENUM_PARAMS_Z(z, num_params, class Arg) #define BOOST_UNORDERED_FUNCTION_PARAMS(z, num_params) \ BOOST_PP_ENUM_##z(num_params, BOOST_UNORDERED_FUNCTION_PARAMS2, _) #define BOOST_UNORDERED_FUNCTION_PARAMS2(z, i, _) \ BOOST_FWD_REF(Arg##i) arg##i #define BOOST_UNORDERED_CALL_PARAMS(z, num_params) \ BOOST_PP_ENUM_##z(num_params, BOOST_UNORDERED_CALL_PARAMS2, _) #define BOOST_UNORDERED_CALL_PARAMS2(z, i, _) \ boost::forward(arg##i) #endif namespace boost { namespace unordered { namespace detail { static const float minimum_max_load_factor = 1e-3f; static const std::size_t default_bucket_count = 11; struct move_tag {}; struct empty_emplace {}; template class unique_table; template class equivalent_table; template class node_constructor; template struct set_extractor; template struct map_extractor; struct no_key; // Explicitly call a destructor #if defined(BOOST_MSVC) #pragma warning(push) #pragma warning(disable:4100) // unreferenced formal parameter #endif template inline void destroy(T* x) { x->~T(); } #if defined(BOOST_MSVC) #pragma warning(pop) #endif //////////////////////////////////////////////////////////////////////////// // convert double to std::size_t inline std::size_t double_to_size_t(double f) { return f >= static_cast( (std::numeric_limits::max)()) ? (std::numeric_limits::max)() : static_cast(f); } //////////////////////////////////////////////////////////////////////////// // primes #define BOOST_UNORDERED_PRIMES \ (5ul)(11ul)(17ul)(29ul)(37ul)(53ul)(67ul)(79ul) \ (97ul)(131ul)(193ul)(257ul)(389ul)(521ul)(769ul) \ (1031ul)(1543ul)(2053ul)(3079ul)(6151ul)(12289ul)(24593ul) \ (49157ul)(98317ul)(196613ul)(393241ul)(786433ul) \ (1572869ul)(3145739ul)(6291469ul)(12582917ul)(25165843ul) \ (50331653ul)(100663319ul)(201326611ul)(402653189ul)(805306457ul) \ (1610612741ul)(3221225473ul)(4294967291ul) template struct prime_list_template { static std::size_t const value[]; #if !defined(SUNPRO_CC) static std::ptrdiff_t const length; #else static std::ptrdiff_t const length = BOOST_PP_SEQ_SIZE(BOOST_UNORDERED_PRIMES); #endif }; template std::size_t const prime_list_template::value[] = { BOOST_PP_SEQ_ENUM(BOOST_UNORDERED_PRIMES) }; #if !defined(SUNPRO_CC) template std::ptrdiff_t const prime_list_template::length = BOOST_PP_SEQ_SIZE(BOOST_UNORDERED_PRIMES); #endif #undef BOOST_UNORDERED_PRIMES typedef prime_list_template prime_list; // no throw inline std::size_t next_prime(std::size_t num) { std::size_t const* const prime_list_begin = prime_list::value; std::size_t const* const prime_list_end = prime_list_begin + prime_list::length; std::size_t const* bound = std::lower_bound(prime_list_begin, prime_list_end, num); if(bound == prime_list_end) bound--; return *bound; } // no throw inline std::size_t prev_prime(std::size_t num) { std::size_t const* const prime_list_begin = prime_list::value; std::size_t const* const prime_list_end = prime_list_begin + prime_list::length; std::size_t const* bound = std::upper_bound(prime_list_begin,prime_list_end, num); if(bound != prime_list_begin) bound--; return *bound; } //////////////////////////////////////////////////////////////////////////// // pair_cast - because some libraries don't have the full pair constructors. #if 0 template inline std::pair pair_cast(std::pair const& x) { return std::pair(Dst1(x.first), Dst2(x.second)); } #define BOOST_UNORDERED_PAIR_CAST(First, Last, Argument) \ ::boost::unordered::detail::pair_cast(Argument) #else #define BOOST_UNORDERED_PAIR_CAST(First, Last, Argument) \ Argument #endif //////////////////////////////////////////////////////////////////////////// // insert_size/initial_size #if !defined(BOOST_NO_STD_DISTANCE) using ::std::distance; #else template inline std::size_t distance(ForwardIterator i, ForwardIterator j) { std::size_t x; std::distance(i, j, x); return x; } #endif template inline std::size_t insert_size(I i, I j, ::boost::forward_traversal_tag) { return std::distance(i, j); } template inline std::size_t insert_size(I, I, ::boost::incrementable_traversal_tag) { return 1; } template inline std::size_t insert_size(I i, I j) { BOOST_DEDUCED_TYPENAME ::boost::iterator_traversal::type iterator_traversal_tag; return insert_size(i, j, iterator_traversal_tag); } template inline std::size_t initial_size(I i, I j, std::size_t num_buckets = ::boost::unordered::detail::default_bucket_count) { return (std::max)(static_cast(insert_size(i, j)) + 1, num_buckets); } }}} #endif