xref: /openbsd-src/gnu/gcc/libstdc++-v3/include/ext/pb_ds/hash_policy.hpp (revision 404b540a9034ac75a6199ad1a32d1bbc7a0d4210)
1*404b540aSrobert // -*- C++ -*-
2*404b540aSrobert 
3*404b540aSrobert // Copyright (C) 2005, 2006 Free Software Foundation, Inc.
4*404b540aSrobert //
5*404b540aSrobert // This file is part of the GNU ISO C++ Library.  This library is free
6*404b540aSrobert // software; you can redistribute it and/or modify it under the terms
7*404b540aSrobert // of the GNU General Public License as published by the Free Software
8*404b540aSrobert // Foundation; either version 2, or (at your option) any later
9*404b540aSrobert // version.
10*404b540aSrobert 
11*404b540aSrobert // This library is distributed in the hope that it will be useful, but
12*404b540aSrobert // WITHOUT ANY WARRANTY; without even the implied warranty of
13*404b540aSrobert // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14*404b540aSrobert // General Public License for more details.
15*404b540aSrobert 
16*404b540aSrobert // You should have received a copy of the GNU General Public License
17*404b540aSrobert // along with this library; see the file COPYING.  If not, write to
18*404b540aSrobert // the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
19*404b540aSrobert // MA 02111-1307, USA.
20*404b540aSrobert 
21*404b540aSrobert // As a special exception, you may use this file as part of a free
22*404b540aSrobert // software library without restriction.  Specifically, if other files
23*404b540aSrobert // instantiate templates or use macros or inline functions from this
24*404b540aSrobert // file, or you compile this file and link it with other files to
25*404b540aSrobert // produce an executable, this file does not by itself cause the
26*404b540aSrobert // resulting executable to be covered by the GNU General Public
27*404b540aSrobert // License.  This exception does not however invalidate any other
28*404b540aSrobert // reasons why the executable file might be covered by the GNU General
29*404b540aSrobert // Public License.
30*404b540aSrobert 
31*404b540aSrobert // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
32*404b540aSrobert 
33*404b540aSrobert // Permission to use, copy, modify, sell, and distribute this software
34*404b540aSrobert // is hereby granted without fee, provided that the above copyright
35*404b540aSrobert // notice appears in all copies, and that both that copyright notice
36*404b540aSrobert // and this permission notice appear in supporting documentation. None
37*404b540aSrobert // of the above authors, nor IBM Haifa Research Laboratories, make any
38*404b540aSrobert // representation about the suitability of this software for any
39*404b540aSrobert // purpose. It is provided "as is" without express or implied
40*404b540aSrobert // warranty.
41*404b540aSrobert 
42*404b540aSrobert /**
43*404b540aSrobert  * @file hash_policy.hpp
44*404b540aSrobert  * Contains hash-related policies.
45*404b540aSrobert  */
46*404b540aSrobert 
47*404b540aSrobert #ifndef PB_DS_HASH_POLICY_HPP
48*404b540aSrobert #define PB_DS_HASH_POLICY_HPP
49*404b540aSrobert 
50*404b540aSrobert #include <algorithm>
51*404b540aSrobert #include <vector>
52*404b540aSrobert #include <cmath>
53*404b540aSrobert #include <ext/pb_ds/exception.hpp>
54*404b540aSrobert #include <ext/pb_ds/detail/type_utils.hpp>
55*404b540aSrobert #include <ext/pb_ds/detail/hash_fn/mask_based_range_hashing.hpp>
56*404b540aSrobert #include <ext/pb_ds/detail/hash_fn/mod_based_range_hashing.hpp>
57*404b540aSrobert #include <ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_size_base.hpp>
58*404b540aSrobert 
59*404b540aSrobert namespace pb_ds
60*404b540aSrobert {
61*404b540aSrobert   // A null hash function, indicating that the combining hash function
62*404b540aSrobert   // is actually a ranged hash function.
63*404b540aSrobert   struct null_hash_fn
64*404b540aSrobert   { };
65*404b540aSrobert 
66*404b540aSrobert   // A null probe function, indicating that the combining probe
67*404b540aSrobert   // function is actually a ranged probe function.
68*404b540aSrobert   struct null_probe_fn
69*404b540aSrobert   { };
70*404b540aSrobert 
71*404b540aSrobert #define PB_DS_CLASS_T_DEC template<typename Size_Type>
72*404b540aSrobert #define PB_DS_CLASS_C_DEC linear_probe_fn<Size_Type>
73*404b540aSrobert 
74*404b540aSrobert   // A probe sequence policy using fixed increments.
75*404b540aSrobert   template<typename Size_Type = size_t>
76*404b540aSrobert   class linear_probe_fn
77*404b540aSrobert   {
78*404b540aSrobert   public:
79*404b540aSrobert     typedef Size_Type size_type;
80*404b540aSrobert 
81*404b540aSrobert     void
82*404b540aSrobert     swap(PB_DS_CLASS_C_DEC& other);
83*404b540aSrobert 
84*404b540aSrobert   protected:
85*404b540aSrobert     // Returns the i-th offset from the hash value.
86*404b540aSrobert     inline size_type
87*404b540aSrobert     operator()(size_type i) const;
88*404b540aSrobert   };
89*404b540aSrobert 
90*404b540aSrobert #include <ext/pb_ds/detail/hash_fn/linear_probe_fn_imp.hpp>
91*404b540aSrobert 
92*404b540aSrobert #undef PB_DS_CLASS_T_DEC
93*404b540aSrobert #undef PB_DS_CLASS_C_DEC
94*404b540aSrobert 
95*404b540aSrobert #define PB_DS_CLASS_T_DEC template<typename Size_Type>
96*404b540aSrobert #define PB_DS_CLASS_C_DEC quadratic_probe_fn<Size_Type>
97*404b540aSrobert 
98*404b540aSrobert   // A probe sequence policy using square increments.
99*404b540aSrobert   template<typename Size_Type = size_t>
100*404b540aSrobert   class quadratic_probe_fn
101*404b540aSrobert   {
102*404b540aSrobert   public:
103*404b540aSrobert     typedef Size_Type size_type;
104*404b540aSrobert 
105*404b540aSrobert     void
106*404b540aSrobert     swap(PB_DS_CLASS_C_DEC& other);
107*404b540aSrobert 
108*404b540aSrobert   protected:
109*404b540aSrobert     // Returns the i-th offset from the hash value.
110*404b540aSrobert     inline size_type
111*404b540aSrobert     operator()(size_type i) const;
112*404b540aSrobert   };
113*404b540aSrobert 
114*404b540aSrobert #include <ext/pb_ds/detail/hash_fn/quadratic_probe_fn_imp.hpp>
115*404b540aSrobert 
116*404b540aSrobert #undef PB_DS_CLASS_T_DEC
117*404b540aSrobert #undef PB_DS_CLASS_C_DEC
118*404b540aSrobert 
119*404b540aSrobert #define PB_DS_CLASS_T_DEC template<typename Size_Type>
120*404b540aSrobert #define PB_DS_CLASS_C_DEC direct_mask_range_hashing<Size_Type>
121*404b540aSrobert 
122*404b540aSrobert   // A mask range-hashing class (uses a bit-mask).
123*404b540aSrobert   template<typename Size_Type = size_t>
124*404b540aSrobert   class direct_mask_range_hashing
125*404b540aSrobert   : public detail::mask_based_range_hashing<Size_Type>
126*404b540aSrobert   {
127*404b540aSrobert   private:
128*404b540aSrobert     typedef detail::mask_based_range_hashing<Size_Type> mask_based_base;
129*404b540aSrobert 
130*404b540aSrobert   public:
131*404b540aSrobert     typedef Size_Type size_type;
132*404b540aSrobert 
133*404b540aSrobert     void
134*404b540aSrobert     swap(PB_DS_CLASS_C_DEC& other);
135*404b540aSrobert 
136*404b540aSrobert   protected:
137*404b540aSrobert     void
138*404b540aSrobert     notify_resized(size_type size);
139*404b540aSrobert 
140*404b540aSrobert     // Transforms the __hash value hash into a ranged-hash value
141*404b540aSrobert     // (using a bit-mask).
142*404b540aSrobert     inline size_type
143*404b540aSrobert     operator()(size_type hash) const;
144*404b540aSrobert   };
145*404b540aSrobert 
146*404b540aSrobert #include <ext/pb_ds/detail/hash_fn/direct_mask_range_hashing_imp.hpp>
147*404b540aSrobert 
148*404b540aSrobert #undef PB_DS_CLASS_T_DEC
149*404b540aSrobert #undef PB_DS_CLASS_C_DEC
150*404b540aSrobert 
151*404b540aSrobert #define PB_DS_CLASS_T_DEC template<typename Size_Type>
152*404b540aSrobert #define PB_DS_CLASS_C_DEC direct_mod_range_hashing<Size_Type>
153*404b540aSrobert 
154*404b540aSrobert   // A mod range-hashing class (uses the modulo function).
155*404b540aSrobert   template<typename Size_Type = size_t>
156*404b540aSrobert   class direct_mod_range_hashing
157*404b540aSrobert   : public detail::mod_based_range_hashing<Size_Type>
158*404b540aSrobert   {
159*404b540aSrobert   public:
160*404b540aSrobert     typedef Size_Type size_type;
161*404b540aSrobert 
162*404b540aSrobert     void
163*404b540aSrobert     swap(PB_DS_CLASS_C_DEC& other);
164*404b540aSrobert 
165*404b540aSrobert   protected:
166*404b540aSrobert     void
167*404b540aSrobert     notify_resized(size_type size);
168*404b540aSrobert 
169*404b540aSrobert     // Transforms the __hash value hash into a ranged-hash value
170*404b540aSrobert     // (using a modulo operation).
171*404b540aSrobert     inline size_type
172*404b540aSrobert     operator()(size_type hash) const;
173*404b540aSrobert 
174*404b540aSrobert   private:
175*404b540aSrobert     typedef detail::mod_based_range_hashing<size_type> mod_based_base;
176*404b540aSrobert   };
177*404b540aSrobert 
178*404b540aSrobert #include <ext/pb_ds/detail/hash_fn/direct_mod_range_hashing_imp.hpp>
179*404b540aSrobert 
180*404b540aSrobert #undef PB_DS_CLASS_T_DEC
181*404b540aSrobert #undef PB_DS_CLASS_C_DEC
182*404b540aSrobert 
183*404b540aSrobert #define PB_DS_CLASS_T_DEC template<bool External_Load_Access, typename Size_Type>
184*404b540aSrobert #define PB_DS_CLASS_C_DEC hash_load_check_resize_trigger<External_Load_Access, Size_Type>
185*404b540aSrobert #define PB_DS_SIZE_BASE_C_DEC detail::hash_load_check_resize_trigger_size_base<Size_Type, External_Load_Access>
186*404b540aSrobert 
187*404b540aSrobert   // A resize trigger policy based on a load check. It keeps the
188*404b540aSrobert   // load factor between some load factors load_min and load_max.
189*404b540aSrobert   template<bool External_Load_Access = false, typename Size_Type = size_t>
190*404b540aSrobert   class hash_load_check_resize_trigger : private PB_DS_SIZE_BASE_C_DEC
191*404b540aSrobert   {
192*404b540aSrobert   public:
193*404b540aSrobert     typedef Size_Type size_type;
194*404b540aSrobert 
195*404b540aSrobert     enum
196*404b540aSrobert       {
197*404b540aSrobert 	external_load_access = External_Load_Access
198*404b540aSrobert       };
199*404b540aSrobert 
200*404b540aSrobert     // Default constructor, or constructor taking load_min and
201*404b540aSrobert     // load_max load factors between which this policy will keep the
202*404b540aSrobert     // actual load.
203*404b540aSrobert     hash_load_check_resize_trigger(float load_min = 0.125,
204*404b540aSrobert 				   float load_max = 0.5);
205*404b540aSrobert 
206*404b540aSrobert     void
207*404b540aSrobert     swap(hash_load_check_resize_trigger& other);
208*404b540aSrobert 
209*404b540aSrobert     virtual
210*404b540aSrobert     ~hash_load_check_resize_trigger();
211*404b540aSrobert 
212*404b540aSrobert     // Returns a pair of the minimal and maximal loads, respectively.
213*404b540aSrobert     inline std::pair<float, float>
214*404b540aSrobert     get_loads() const;
215*404b540aSrobert 
216*404b540aSrobert     // Sets the loads through a pair of the minimal and maximal
217*404b540aSrobert     // loads, respectively.
218*404b540aSrobert     void
219*404b540aSrobert     set_loads(std::pair<float, float> load_pair);
220*404b540aSrobert 
221*404b540aSrobert   protected:
222*404b540aSrobert     inline void
223*404b540aSrobert     notify_insert_search_start();
224*404b540aSrobert 
225*404b540aSrobert     inline void
226*404b540aSrobert     notify_insert_search_collision();
227*404b540aSrobert 
228*404b540aSrobert     inline void
229*404b540aSrobert     notify_insert_search_end();
230*404b540aSrobert 
231*404b540aSrobert     inline void
232*404b540aSrobert     notify_find_search_start();
233*404b540aSrobert 
234*404b540aSrobert     inline void
235*404b540aSrobert     notify_find_search_collision();
236*404b540aSrobert 
237*404b540aSrobert     inline void
238*404b540aSrobert     notify_find_search_end();
239*404b540aSrobert 
240*404b540aSrobert     inline void
241*404b540aSrobert     notify_erase_search_start();
242*404b540aSrobert 
243*404b540aSrobert     inline void
244*404b540aSrobert     notify_erase_search_collision();
245*404b540aSrobert 
246*404b540aSrobert     inline void
247*404b540aSrobert     notify_erase_search_end();
248*404b540aSrobert 
249*404b540aSrobert     // Notifies an element was inserted. The total number of entries
250*404b540aSrobert     // in the table is num_entries.
251*404b540aSrobert     inline void
252*404b540aSrobert     notify_inserted(size_type num_entries);
253*404b540aSrobert 
254*404b540aSrobert     inline void
255*404b540aSrobert     notify_erased(size_type num_entries);
256*404b540aSrobert 
257*404b540aSrobert     // Notifies the table was cleared.
258*404b540aSrobert     void
259*404b540aSrobert     notify_cleared();
260*404b540aSrobert 
261*404b540aSrobert     // Notifies the table was resized as a result of this object's
262*404b540aSrobert     // signifying that a resize is needed.
263*404b540aSrobert     void
264*404b540aSrobert     notify_resized(size_type new_size);
265*404b540aSrobert 
266*404b540aSrobert     void
267*404b540aSrobert     notify_externally_resized(size_type new_size);
268*404b540aSrobert 
269*404b540aSrobert     inline bool
270*404b540aSrobert     is_resize_needed() const;
271*404b540aSrobert 
272*404b540aSrobert     inline bool
273*404b540aSrobert     is_grow_needed(size_type size, size_type num_entries) const;
274*404b540aSrobert 
275*404b540aSrobert   private:
276*404b540aSrobert     virtual void
277*404b540aSrobert     do_resize(size_type new_size);
278*404b540aSrobert 
279*404b540aSrobert     typedef PB_DS_SIZE_BASE_C_DEC size_base;
280*404b540aSrobert 
281*404b540aSrobert #ifdef _GLIBCXX_DEBUG
282*404b540aSrobert     void
283*404b540aSrobert     assert_valid() const;
284*404b540aSrobert #endif
285*404b540aSrobert 
286*404b540aSrobert     float 	m_load_min;
287*404b540aSrobert     float 	m_load_max;
288*404b540aSrobert     size_type 	m_next_shrink_size;
289*404b540aSrobert     size_type 	m_next_grow_size;
290*404b540aSrobert     bool 	m_resize_needed;
291*404b540aSrobert   };
292*404b540aSrobert 
293*404b540aSrobert #include <ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_imp.hpp>
294*404b540aSrobert 
295*404b540aSrobert #undef PB_DS_CLASS_T_DEC
296*404b540aSrobert #undef PB_DS_CLASS_C_DEC
297*404b540aSrobert #undef PB_DS_SIZE_BASE_C_DEC
298*404b540aSrobert 
299*404b540aSrobert #define PB_DS_CLASS_T_DEC template<bool External_Load_Access, typename Size_Type>
300*404b540aSrobert #define PB_DS_CLASS_C_DEC cc_hash_max_collision_check_resize_trigger<External_Load_Access, Size_Type>
301*404b540aSrobert 
302*404b540aSrobert   // A resize trigger policy based on collision checks. It keeps the
303*404b540aSrobert   // simulated load factor lower than some given load factor.
304*404b540aSrobert   template<bool External_Load_Access = false, typename Size_Type = size_t>
305*404b540aSrobert   class cc_hash_max_collision_check_resize_trigger
306*404b540aSrobert   {
307*404b540aSrobert   public:
308*404b540aSrobert     typedef Size_Type size_type;
309*404b540aSrobert 
310*404b540aSrobert     enum
311*404b540aSrobert       {
312*404b540aSrobert 	external_load_access = External_Load_Access
313*404b540aSrobert       };
314*404b540aSrobert 
315*404b540aSrobert     // Default constructor, or constructor taking load, a __load
316*404b540aSrobert     // factor which it will attempt to maintain.
317*404b540aSrobert     cc_hash_max_collision_check_resize_trigger(float load = 0.5);
318*404b540aSrobert 
319*404b540aSrobert     void
320*404b540aSrobert     swap(PB_DS_CLASS_C_DEC& other);
321*404b540aSrobert 
322*404b540aSrobert     // Returns the current load.
323*404b540aSrobert     inline float
324*404b540aSrobert     get_load() const;
325*404b540aSrobert 
326*404b540aSrobert     // Sets the load; does not resize the container.
327*404b540aSrobert     void
328*404b540aSrobert     set_load(float load);
329*404b540aSrobert 
330*404b540aSrobert   protected:
331*404b540aSrobert     inline void
332*404b540aSrobert     notify_insert_search_start();
333*404b540aSrobert 
334*404b540aSrobert     inline void
335*404b540aSrobert     notify_insert_search_collision();
336*404b540aSrobert 
337*404b540aSrobert     inline void
338*404b540aSrobert     notify_insert_search_end();
339*404b540aSrobert 
340*404b540aSrobert     inline void
341*404b540aSrobert     notify_find_search_start();
342*404b540aSrobert 
343*404b540aSrobert     inline void
344*404b540aSrobert     notify_find_search_collision();
345*404b540aSrobert 
346*404b540aSrobert     inline void
347*404b540aSrobert     notify_find_search_end();
348*404b540aSrobert 
349*404b540aSrobert     inline void
350*404b540aSrobert     notify_erase_search_start();
351*404b540aSrobert 
352*404b540aSrobert     inline void
353*404b540aSrobert     notify_erase_search_collision();
354*404b540aSrobert 
355*404b540aSrobert     inline void
356*404b540aSrobert     notify_erase_search_end();
357*404b540aSrobert 
358*404b540aSrobert     inline void
359*404b540aSrobert     notify_inserted(size_type num_entries);
360*404b540aSrobert 
361*404b540aSrobert     inline void
362*404b540aSrobert     notify_erased(size_type num_entries);
363*404b540aSrobert 
364*404b540aSrobert     void
365*404b540aSrobert     notify_cleared();
366*404b540aSrobert 
367*404b540aSrobert     // Notifies the table was resized as a result of this object's
368*404b540aSrobert     // signifying that a resize is needed.
369*404b540aSrobert     void
370*404b540aSrobert     notify_resized(size_type new_size);
371*404b540aSrobert 
372*404b540aSrobert     void
373*404b540aSrobert     notify_externally_resized(size_type new_size);
374*404b540aSrobert 
375*404b540aSrobert     inline bool
376*404b540aSrobert     is_resize_needed() const;
377*404b540aSrobert 
378*404b540aSrobert     inline bool
379*404b540aSrobert     is_grow_needed(size_type size, size_type num_entries) const;
380*404b540aSrobert 
381*404b540aSrobert   private:
382*404b540aSrobert     void
383*404b540aSrobert     calc_max_num_coll();
384*404b540aSrobert 
385*404b540aSrobert     inline void
386*404b540aSrobert     calc_resize_needed();
387*404b540aSrobert 
388*404b540aSrobert     float 	m_load;
389*404b540aSrobert     size_type 	m_size;
390*404b540aSrobert     size_type 	m_num_col;
391*404b540aSrobert     size_type 	m_max_col;
392*404b540aSrobert     bool 	m_resize_needed;
393*404b540aSrobert   };
394*404b540aSrobert 
395*404b540aSrobert #include <ext/pb_ds/detail/resize_policy/cc_hash_max_collision_check_resize_trigger_imp.hpp>
396*404b540aSrobert 
397*404b540aSrobert #undef PB_DS_CLASS_T_DEC
398*404b540aSrobert #undef PB_DS_CLASS_C_DEC
399*404b540aSrobert 
400*404b540aSrobert #define PB_DS_CLASS_T_DEC template<typename Size_Type>
401*404b540aSrobert #define PB_DS_CLASS_C_DEC hash_exponential_size_policy<Size_Type>
402*404b540aSrobert 
403*404b540aSrobert   // A size policy whose sequence of sizes form an exponential
404*404b540aSrobert   // sequence (typically powers of 2.
405*404b540aSrobert   template<typename Size_Type = size_t>
406*404b540aSrobert   class hash_exponential_size_policy
407*404b540aSrobert   {
408*404b540aSrobert   public:
409*404b540aSrobert     typedef Size_Type size_type;
410*404b540aSrobert 
411*404b540aSrobert     // Default constructor, or onstructor taking a start_size, or
412*404b540aSrobert     // constructor taking a start size and grow_factor. The policy
413*404b540aSrobert     // will use the sequence of sizes start_size, start_size*
414*404b540aSrobert     // grow_factor, start_size* grow_factor^2, ...
415*404b540aSrobert     hash_exponential_size_policy(size_type start_size = 8,
416*404b540aSrobert 				 size_type grow_factor = 2);
417*404b540aSrobert 
418*404b540aSrobert     void
419*404b540aSrobert     swap(PB_DS_CLASS_C_DEC& other);
420*404b540aSrobert 
421*404b540aSrobert   protected:
422*404b540aSrobert     size_type
423*404b540aSrobert     get_nearest_larger_size(size_type size) const;
424*404b540aSrobert 
425*404b540aSrobert     size_type
426*404b540aSrobert     get_nearest_smaller_size(size_type size) const;
427*404b540aSrobert 
428*404b540aSrobert   private:
429*404b540aSrobert     size_type m_start_size;
430*404b540aSrobert     size_type m_grow_factor;
431*404b540aSrobert   };
432*404b540aSrobert 
433*404b540aSrobert #include <ext/pb_ds/detail/resize_policy/hash_exponential_size_policy_imp.hpp>
434*404b540aSrobert 
435*404b540aSrobert #undef PB_DS_CLASS_T_DEC
436*404b540aSrobert #undef PB_DS_CLASS_C_DEC
437*404b540aSrobert 
438*404b540aSrobert #define PB_DS_CLASS_T_DEC
439*404b540aSrobert #define PB_DS_CLASS_C_DEC hash_prime_size_policy
440*404b540aSrobert 
441*404b540aSrobert   // A size policy whose sequence of sizes form a nearly-exponential
442*404b540aSrobert   // sequence of primes.
443*404b540aSrobert   class hash_prime_size_policy
444*404b540aSrobert   {
445*404b540aSrobert   public:
446*404b540aSrobert     // Size type.
447*404b540aSrobert     typedef size_t size_type;
448*404b540aSrobert 
449*404b540aSrobert     // Default constructor, or onstructor taking a start_size The
450*404b540aSrobert     // policy will use the sequence of sizes approximately
451*404b540aSrobert     // start_size, start_size* 2, start_size* 2^2, ...
452*404b540aSrobert     hash_prime_size_policy(size_type start_size = 8);
453*404b540aSrobert 
454*404b540aSrobert     inline void
455*404b540aSrobert     swap(PB_DS_CLASS_C_DEC& other);
456*404b540aSrobert 
457*404b540aSrobert   protected:
458*404b540aSrobert     size_type
459*404b540aSrobert     get_nearest_larger_size(size_type size) const;
460*404b540aSrobert 
461*404b540aSrobert     size_type
462*404b540aSrobert     get_nearest_smaller_size(size_type size) const;
463*404b540aSrobert 
464*404b540aSrobert   private:
465*404b540aSrobert     size_type m_start_size;
466*404b540aSrobert   };
467*404b540aSrobert 
468*404b540aSrobert #include <ext/pb_ds/detail/resize_policy/hash_prime_size_policy_imp.hpp>
469*404b540aSrobert 
470*404b540aSrobert #undef PB_DS_CLASS_T_DEC
471*404b540aSrobert #undef PB_DS_CLASS_C_DEC
472*404b540aSrobert 
473*404b540aSrobert #define PB_DS_CLASS_T_DEC template<typename Size_Policy, typename Trigger_Policy, bool External_Size_Access, typename Size_Type>
474*404b540aSrobert 
475*404b540aSrobert #define PB_DS_CLASS_C_DEC hash_standard_resize_policy<Size_Policy, Trigger_Policy, External_Size_Access, Size_Type>
476*404b540aSrobert 
477*404b540aSrobert   // A resize policy which delegates operations to size and trigger policies.
478*404b540aSrobert   template<typename Size_Policy = hash_exponential_size_policy<>,
479*404b540aSrobert 	   typename Trigger_Policy = hash_load_check_resize_trigger<>,
480*404b540aSrobert 	   bool External_Size_Access = false,
481*404b540aSrobert 	   typename Size_Type = size_t>
482*404b540aSrobert   class hash_standard_resize_policy
483*404b540aSrobert   : public Size_Policy, public Trigger_Policy
484*404b540aSrobert   {
485*404b540aSrobert   public:
486*404b540aSrobert     typedef Size_Type 		size_type;
487*404b540aSrobert     typedef Trigger_Policy 	trigger_policy;
488*404b540aSrobert     typedef Size_Policy 	size_policy;
489*404b540aSrobert 
490*404b540aSrobert     enum
491*404b540aSrobert       {
492*404b540aSrobert 	external_size_access = External_Size_Access
493*404b540aSrobert       };
494*404b540aSrobert 
495*404b540aSrobert     // Default constructor.
496*404b540aSrobert     hash_standard_resize_policy();
497*404b540aSrobert 
498*404b540aSrobert     // constructor taking some policies r_size_policy will be copied
499*404b540aSrobert     // by the Size_Policy object of this object.
500*404b540aSrobert     hash_standard_resize_policy(const Size_Policy& r_size_policy);
501*404b540aSrobert 
502*404b540aSrobert     // constructor taking some policies. r_size_policy will be
503*404b540aSrobert     // copied by the Size_Policy object of this
504*404b540aSrobert     // object. r_trigger_policy will be copied by the Trigger_Policy
505*404b540aSrobert     // object of this object.
506*404b540aSrobert     hash_standard_resize_policy(const Size_Policy& r_size_policy,
507*404b540aSrobert 				const Trigger_Policy& r_trigger_policy);
508*404b540aSrobert 
509*404b540aSrobert     virtual
510*404b540aSrobert     ~hash_standard_resize_policy();
511*404b540aSrobert 
512*404b540aSrobert     inline void
513*404b540aSrobert     swap(PB_DS_CLASS_C_DEC& other);
514*404b540aSrobert 
515*404b540aSrobert     // Access to the Size_Policy object used.
516*404b540aSrobert     Size_Policy&
517*404b540aSrobert     get_size_policy();
518*404b540aSrobert 
519*404b540aSrobert     // Const access to the Size_Policy object used.
520*404b540aSrobert     const Size_Policy&
521*404b540aSrobert     get_size_policy() const;
522*404b540aSrobert 
523*404b540aSrobert     // Access to the Trigger_Policy object used.
524*404b540aSrobert     Trigger_Policy&
525*404b540aSrobert     get_trigger_policy();
526*404b540aSrobert 
527*404b540aSrobert     // Access to the Trigger_Policy object used.
528*404b540aSrobert     const Trigger_Policy&
529*404b540aSrobert     get_trigger_policy() const;
530*404b540aSrobert 
531*404b540aSrobert     // Returns the actual size of the container.
532*404b540aSrobert     inline size_type
533*404b540aSrobert     get_actual_size() const;
534*404b540aSrobert 
535*404b540aSrobert     // Resizes the container to suggested_new_size, a suggested size
536*404b540aSrobert     // (the actual size will be determined by the Size_Policy
537*404b540aSrobert     // object).
538*404b540aSrobert     void
539*404b540aSrobert     resize(size_type suggested_new_size);
540*404b540aSrobert 
541*404b540aSrobert   protected:
542*404b540aSrobert     inline void
543*404b540aSrobert     notify_insert_search_start();
544*404b540aSrobert 
545*404b540aSrobert     inline void
546*404b540aSrobert     notify_insert_search_collision();
547*404b540aSrobert 
548*404b540aSrobert     inline void
549*404b540aSrobert     notify_insert_search_end();
550*404b540aSrobert 
551*404b540aSrobert     inline void
552*404b540aSrobert     notify_find_search_start();
553*404b540aSrobert 
554*404b540aSrobert     inline void
555*404b540aSrobert     notify_find_search_collision();
556*404b540aSrobert 
557*404b540aSrobert     inline void
558*404b540aSrobert     notify_find_search_end();
559*404b540aSrobert 
560*404b540aSrobert     inline void
561*404b540aSrobert     notify_erase_search_start();
562*404b540aSrobert 
563*404b540aSrobert     inline void
564*404b540aSrobert     notify_erase_search_collision();
565*404b540aSrobert 
566*404b540aSrobert     inline void
567*404b540aSrobert     notify_erase_search_end();
568*404b540aSrobert 
569*404b540aSrobert     inline void
570*404b540aSrobert     notify_inserted(size_type num_e);
571*404b540aSrobert 
572*404b540aSrobert     inline void
573*404b540aSrobert     notify_erased(size_type num_e);
574*404b540aSrobert 
575*404b540aSrobert     void
576*404b540aSrobert     notify_cleared();
577*404b540aSrobert 
578*404b540aSrobert     void
579*404b540aSrobert     notify_resized(size_type new_size);
580*404b540aSrobert 
581*404b540aSrobert     inline bool
582*404b540aSrobert     is_resize_needed() const;
583*404b540aSrobert 
584*404b540aSrobert     // Queries what the new size should be, when the container is
585*404b540aSrobert     // resized naturally. The current __size of the container is
586*404b540aSrobert     // size, and the number of used entries within the container is
587*404b540aSrobert     // num_used_e.
588*404b540aSrobert     size_type
589*404b540aSrobert     get_new_size(size_type size, size_type num_used_e) const;
590*404b540aSrobert 
591*404b540aSrobert   private:
592*404b540aSrobert     // Resizes to new_size.
593*404b540aSrobert     virtual void
594*404b540aSrobert     do_resize(size_type new_size);
595*404b540aSrobert 
596*404b540aSrobert     typedef Trigger_Policy trigger_policy_base;
597*404b540aSrobert 
598*404b540aSrobert     typedef Size_Policy size_policy_base;
599*404b540aSrobert 
600*404b540aSrobert     size_type m_size;
601*404b540aSrobert   };
602*404b540aSrobert 
603*404b540aSrobert #include <ext/pb_ds/detail/resize_policy/hash_standard_resize_policy_imp.hpp>
604*404b540aSrobert 
605*404b540aSrobert #undef PB_DS_CLASS_T_DEC
606*404b540aSrobert #undef PB_DS_CLASS_C_DEC
607*404b540aSrobert 
608*404b540aSrobert } // namespace pb_ds
609*404b540aSrobert 
610*404b540aSrobert #endif
611