1169691Skan// -*- C++ -*- 2169691Skan 3169691Skan// Copyright (C) 2005, 2006 Free Software Foundation, Inc. 4169691Skan// 5169691Skan// This file is part of the GNU ISO C++ Library. This library is free 6169691Skan// software; you can redistribute it and/or modify it under the terms 7169691Skan// of the GNU General Public License as published by the Free Software 8169691Skan// Foundation; either version 2, or (at your option) any later 9169691Skan// version. 10169691Skan 11169691Skan// This library is distributed in the hope that it will be useful, but 12169691Skan// WITHOUT ANY WARRANTY; without even the implied warranty of 13169691Skan// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14169691Skan// General Public License for more details. 15169691Skan 16169691Skan// You should have received a copy of the GNU General Public License along 17169691Skan// with this library; see the file COPYING. If not, write to the Free 18169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 19169691Skan// USA. 20169691Skan 21169691Skan// As a special exception, you may use this file as part of a free 22169691Skan// software library without restriction. Specifically, if other files 23169691Skan// instantiate templates or use macros or inline functions from this 24169691Skan// file, or you compile this file and link it with other files to 25169691Skan// produce an executable, this file does not by itself cause the 26169691Skan// resulting executable to be covered by the GNU General Public 27169691Skan// License. This exception does not however invalidate any other 28169691Skan// reasons why the executable file might be covered by the GNU General 29169691Skan// Public License. 30169691Skan 31169691Skan// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. 32169691Skan 33169691Skan// Permission to use, copy, modify, sell, and distribute this software 34169691Skan// is hereby granted without fee, provided that the above copyright 35169691Skan// notice appears in all copies, and that both that copyright notice 36169691Skan// and this permission notice appear in supporting documentation. None 37169691Skan// of the above authors, nor IBM Haifa Research Laboratories, make any 38169691Skan// representation about the suitability of this software for any 39169691Skan// purpose. It is provided "as is" without express or implied 40169691Skan// warranty. 41169691Skan 42169691Skan/** 43169691Skan * @file hash_prime_size_policy_imp.hpp 44169691Skan * Contains a resize size policy implementation. 45169691Skan */ 46169691Skan 47169691Skannamespace detail 48169691Skan{ 49169691Skan enum 50169691Skan { 51169691Skan num_distinct_sizes_32_bit = 30, 52169691Skan num_distinct_sizes_64_bit = 62, 53169691Skan num_distinct_sizes = sizeof(std::size_t) != 8 ? 54169691Skan num_distinct_sizes_32_bit : num_distinct_sizes_64_bit, 55169691Skan }; 56169691Skan 57169691Skan // Originally taken from the SGI implementation; acknowledged in the docs. 58169691Skan // Further modified (for 64 bits) from tr1's hashtable. 59169691Skan static const std::size_t g_a_sizes[num_distinct_sizes_64_bit] = 60169691Skan { 61169691Skan /* 0 */ 5ul, 62169691Skan /* 1 */ 11ul, 63169691Skan /* 2 */ 23ul, 64169691Skan /* 3 */ 47ul, 65169691Skan /* 4 */ 97ul, 66169691Skan /* 5 */ 199ul, 67169691Skan /* 6 */ 409ul, 68169691Skan /* 7 */ 823ul, 69169691Skan /* 8 */ 1741ul, 70169691Skan /* 9 */ 3469ul, 71169691Skan /* 10 */ 6949ul, 72169691Skan /* 11 */ 14033ul, 73169691Skan /* 12 */ 28411ul, 74169691Skan /* 13 */ 57557ul, 75169691Skan /* 14 */ 116731ul, 76169691Skan /* 15 */ 236897ul, 77169691Skan /* 16 */ 480881ul, 78169691Skan /* 17 */ 976369ul, 79169691Skan /* 18 */ 1982627ul, 80169691Skan /* 19 */ 4026031ul, 81169691Skan /* 20 */ 8175383ul, 82169691Skan /* 21 */ 16601593ul, 83169691Skan /* 22 */ 33712729ul, 84169691Skan /* 23 */ 68460391ul, 85169691Skan /* 24 */ 139022417ul, 86169691Skan /* 25 */ 282312799ul, 87169691Skan /* 26 */ 573292817ul, 88169691Skan /* 27 */ 1164186217ul, 89169691Skan /* 28 */ 2364114217ul, 90169691Skan /* 29 */ 4294967291ul, 91169691Skan /* 30 */ (std::size_t)8589934583ull, 92169691Skan /* 31 */ (std::size_t)17179869143ull, 93169691Skan /* 32 */ (std::size_t)34359738337ull, 94169691Skan /* 33 */ (std::size_t)68719476731ull, 95169691Skan /* 34 */ (std::size_t)137438953447ull, 96169691Skan /* 35 */ (std::size_t)274877906899ull, 97169691Skan /* 36 */ (std::size_t)549755813881ull, 98169691Skan /* 37 */ (std::size_t)1099511627689ull, 99169691Skan /* 38 */ (std::size_t)2199023255531ull, 100169691Skan /* 39 */ (std::size_t)4398046511093ull, 101169691Skan /* 40 */ (std::size_t)8796093022151ull, 102169691Skan /* 41 */ (std::size_t)17592186044399ull, 103169691Skan /* 42 */ (std::size_t)35184372088777ull, 104169691Skan /* 43 */ (std::size_t)70368744177643ull, 105169691Skan /* 44 */ (std::size_t)140737488355213ull, 106169691Skan /* 45 */ (std::size_t)281474976710597ull, 107169691Skan /* 46 */ (std::size_t)562949953421231ull, 108169691Skan /* 47 */ (std::size_t)1125899906842597ull, 109169691Skan /* 48 */ (std::size_t)2251799813685119ull, 110169691Skan /* 49 */ (std::size_t)4503599627370449ull, 111169691Skan /* 50 */ (std::size_t)9007199254740881ull, 112169691Skan /* 51 */ (std::size_t)18014398509481951ull, 113169691Skan /* 52 */ (std::size_t)36028797018963913ull, 114169691Skan /* 53 */ (std::size_t)72057594037927931ull, 115169691Skan /* 54 */ (std::size_t)144115188075855859ull, 116169691Skan /* 55 */ (std::size_t)288230376151711717ull, 117169691Skan /* 56 */ (std::size_t)576460752303423433ull, 118169691Skan /* 57 */ (std::size_t)1152921504606846883ull, 119169691Skan /* 58 */ (std::size_t)2305843009213693951ull, 120169691Skan /* 59 */ (std::size_t)4611686018427387847ull, 121169691Skan /* 60 */ (std::size_t)9223372036854775783ull, 122169691Skan /* 61 */ (std::size_t)18446744073709551557ull, 123169691Skan }; 124169691Skan 125169691Skan} // namespace detail 126169691Skan 127169691SkanPB_DS_CLASS_T_DEC 128169691Skaninline 129169691SkanPB_DS_CLASS_C_DEC:: 130169691Skanhash_prime_size_policy(size_type n) : m_start_size(n) 131169691Skan{ m_start_size = get_nearest_larger_size(n); } 132169691Skan 133169691SkanPB_DS_CLASS_T_DEC 134169691Skaninline void 135169691SkanPB_DS_CLASS_C_DEC:: 136169691Skanswap(PB_DS_CLASS_C_DEC& other) 137169691Skan{ std::swap(m_start_size, other.m_start_size); } 138169691Skan 139169691SkanPB_DS_CLASS_T_DEC 140169691Skaninline PB_DS_CLASS_C_DEC::size_type 141169691SkanPB_DS_CLASS_C_DEC:: 142169691Skanget_nearest_larger_size(size_type n) const 143169691Skan{ 144169691Skan const std::size_t* const p_upper = std::upper_bound(detail::g_a_sizes, 145169691Skan detail::g_a_sizes + detail::num_distinct_sizes, n); 146169691Skan 147169691Skan if (p_upper == detail::g_a_sizes + detail::num_distinct_sizes) 148169691Skan __throw_resize_error(); 149169691Skan return *p_upper; 150169691Skan} 151169691Skan 152169691SkanPB_DS_CLASS_T_DEC 153169691Skaninline PB_DS_CLASS_C_DEC::size_type 154169691SkanPB_DS_CLASS_C_DEC:: 155169691Skanget_nearest_smaller_size(size_type n) const 156169691Skan{ 157169691Skan const size_t* p_lower = std::lower_bound(detail::g_a_sizes, 158169691Skan detail::g_a_sizes + detail::num_distinct_sizes, n); 159169691Skan 160169691Skan if (*p_lower >= n && p_lower != detail::g_a_sizes) 161169691Skan --p_lower; 162169691Skan if (*p_lower < m_start_size) 163169691Skan return m_start_size; 164169691Skan return *p_lower; 165169691Skan} 166