libstdc++
hash_prime_size_policy_imp.hpp
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // Copyright (C) 2005, 2006, 2009, 2010 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the terms
00007 // of the GNU General Public License as published by the Free Software
00008 // Foundation; either version 3, or (at your option) any later
00009 // version.
00010 
00011 // This library is distributed in the hope that it will be useful, but
00012 // WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
00026 
00027 // Permission to use, copy, modify, sell, and distribute this software
00028 // is hereby granted without fee, provided that the above copyright
00029 // notice appears in all copies, and that both that copyright notice
00030 // and this permission notice appear in supporting documentation. None
00031 // of the above authors, nor IBM Haifa Research Laboratories, make any
00032 // representation about the suitability of this software for any
00033 // purpose. It is provided "as is" without express or implied
00034 // warranty.
00035 
00036 /**
00037  * @file hash_prime_size_policy_imp.hpp
00038  * Contains a resize size policy implementation.
00039  */
00040 
00041 #pragma GCC system_header
00042 
00043 namespace detail
00044 {
00045   enum
00046     {
00047       num_distinct_sizes_32_bit = 30,
00048       num_distinct_sizes_64_bit = 62,
00049       num_distinct_sizes = sizeof(std::size_t) != 8 ? 
00050             num_distinct_sizes_32_bit : num_distinct_sizes_64_bit,  
00051     };
00052 
00053   // Originally taken from the SGI implementation; acknowledged in the docs.
00054   // Further modified (for 64 bits) from tr1's hashtable.
00055   static const std::size_t g_a_sizes[num_distinct_sizes_64_bit] =
00056     {
00057       /* 0     */              5ul,
00058       /* 1     */              11ul, 
00059       /* 2     */              23ul, 
00060       /* 3     */              47ul, 
00061       /* 4     */              97ul, 
00062       /* 5     */              199ul, 
00063       /* 6     */              409ul, 
00064       /* 7     */              823ul, 
00065       /* 8     */              1741ul, 
00066       /* 9     */              3469ul, 
00067       /* 10    */              6949ul, 
00068       /* 11    */              14033ul, 
00069       /* 12    */              28411ul, 
00070       /* 13    */              57557ul, 
00071       /* 14    */              116731ul, 
00072       /* 15    */              236897ul,
00073       /* 16    */              480881ul, 
00074       /* 17    */              976369ul,
00075       /* 18    */              1982627ul, 
00076       /* 19    */              4026031ul,
00077       /* 20    */              8175383ul, 
00078       /* 21    */              16601593ul, 
00079       /* 22    */              33712729ul,
00080       /* 23    */              68460391ul, 
00081       /* 24    */              139022417ul, 
00082       /* 25    */              282312799ul, 
00083       /* 26    */              573292817ul, 
00084       /* 27    */              1164186217ul,
00085       /* 28    */              2364114217ul, 
00086       /* 29    */              4294967291ul,
00087       /* 30    */ (std::size_t)8589934583ull,
00088       /* 31    */ (std::size_t)17179869143ull,
00089       /* 32    */ (std::size_t)34359738337ull,
00090       /* 33    */ (std::size_t)68719476731ull,
00091       /* 34    */ (std::size_t)137438953447ull,
00092       /* 35    */ (std::size_t)274877906899ull,
00093       /* 36    */ (std::size_t)549755813881ull,
00094       /* 37    */ (std::size_t)1099511627689ull,
00095       /* 38    */ (std::size_t)2199023255531ull,
00096       /* 39    */ (std::size_t)4398046511093ull,
00097       /* 40    */ (std::size_t)8796093022151ull,
00098       /* 41    */ (std::size_t)17592186044399ull,
00099       /* 42    */ (std::size_t)35184372088777ull,
00100       /* 43    */ (std::size_t)70368744177643ull,
00101       /* 44    */ (std::size_t)140737488355213ull,
00102       /* 45    */ (std::size_t)281474976710597ull,
00103       /* 46    */ (std::size_t)562949953421231ull, 
00104       /* 47    */ (std::size_t)1125899906842597ull,
00105       /* 48    */ (std::size_t)2251799813685119ull, 
00106       /* 49    */ (std::size_t)4503599627370449ull,
00107       /* 50    */ (std::size_t)9007199254740881ull, 
00108       /* 51    */ (std::size_t)18014398509481951ull,
00109       /* 52    */ (std::size_t)36028797018963913ull, 
00110       /* 53    */ (std::size_t)72057594037927931ull,
00111       /* 54    */ (std::size_t)144115188075855859ull,
00112       /* 55    */ (std::size_t)288230376151711717ull,
00113       /* 56    */ (std::size_t)576460752303423433ull,
00114       /* 57    */ (std::size_t)1152921504606846883ull,
00115       /* 58    */ (std::size_t)2305843009213693951ull,
00116       /* 59    */ (std::size_t)4611686018427387847ull,
00117       /* 60    */ (std::size_t)9223372036854775783ull,
00118       /* 61    */ (std::size_t)18446744073709551557ull,
00119     };
00120 
00121 } // namespace detail
00122 
00123 PB_DS_CLASS_T_DEC
00124 inline
00125 PB_DS_CLASS_C_DEC::
00126 hash_prime_size_policy(size_type n) : m_start_size(n)
00127 { m_start_size = get_nearest_larger_size(n); }
00128 
00129 PB_DS_CLASS_T_DEC
00130 inline void
00131 PB_DS_CLASS_C_DEC::
00132 swap(PB_DS_CLASS_C_DEC& other)
00133 { std::swap(m_start_size, other.m_start_size); }
00134 
00135 PB_DS_CLASS_T_DEC
00136 inline PB_DS_CLASS_C_DEC::size_type
00137 PB_DS_CLASS_C_DEC::
00138 get_nearest_larger_size(size_type n) const
00139 {
00140   const std::size_t* const p_upper = std::upper_bound(detail::g_a_sizes, 
00141              detail::g_a_sizes + detail::num_distinct_sizes, n);
00142 
00143   if (p_upper == detail::g_a_sizes + detail::num_distinct_sizes)
00144     __throw_resize_error();
00145   return *p_upper;
00146 }
00147 
00148 PB_DS_CLASS_T_DEC
00149 inline PB_DS_CLASS_C_DEC::size_type
00150 PB_DS_CLASS_C_DEC::
00151 get_nearest_smaller_size(size_type n) const
00152 {
00153   const std::size_t* p_lower = std::lower_bound(detail::g_a_sizes, 
00154                detail::g_a_sizes + detail::num_distinct_sizes, n);
00155 
00156   if (*p_lower >= n &&  p_lower != detail::g_a_sizes)
00157     --p_lower;
00158   if (*p_lower < m_start_size)
00159     return m_start_size;
00160   return *p_lower;
00161 }