New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
table.hpp in vendors/XIOS/current/extern/boost/include/boost/unordered/detail – NEMO

source: vendors/XIOS/current/extern/boost/include/boost/unordered/detail/table.hpp @ 3408

Last change on this file since 3408 was 3408, checked in by rblod, 12 years ago

importing initial XIOS vendor drop

  • Property svn:keywords set to Id
File size: 23.3 KB
Line 
1
2// Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard.
3// Copyright (C) 2005-2009 Daniel James
4// Distributed under the Boost Software License, Version 1.0. (See accompanying
5// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7#ifndef BOOST_UNORDERED_DETAIL_ALL_HPP_INCLUDED
8#define BOOST_UNORDERED_DETAIL_ALL_HPP_INCLUDED
9
10#include <cstddef>
11#include <stdexcept>
12#include <algorithm>
13#include <boost/config/no_tr1/cmath.hpp>
14#include <boost/iterator/iterator_categories.hpp>
15#include <boost/throw_exception.hpp>
16
17#include <boost/unordered/detail/buckets.hpp>
18
19namespace boost { namespace unordered_detail {
20
21    ////////////////////////////////////////////////////////////////////////////
22    // Helper methods
23
24    // strong exception safety, no side effects
25    template <class T>
26    inline bool hash_table<T>::equal(
27        key_type const& k, value_type const& v) const
28    {
29        return this->key_eq()(k, get_key(v));
30    }
31
32    // strong exception safety, no side effects
33    template <class T>
34    template <class Key, class Pred>
35    inline BOOST_DEDUCED_TYPENAME T::node_ptr
36        hash_table<T>::find_iterator(bucket_ptr bucket, Key const& k,
37            Pred const& eq) const
38    {
39        node_ptr it = bucket->next_;
40        while (BOOST_UNORDERED_BORLAND_BOOL(it) &&
41            !eq(k, get_key(node::get_value(it))))
42        {
43            it = node::next_group(it);
44        }
45
46        return it;
47    }
48
49    // strong exception safety, no side effects
50    template <class T>
51    inline BOOST_DEDUCED_TYPENAME T::node_ptr
52        hash_table<T>::find_iterator(
53            bucket_ptr bucket, key_type const& k) const
54    {
55        node_ptr it = bucket->next_;
56        while (BOOST_UNORDERED_BORLAND_BOOL(it) &&
57            !equal(k, node::get_value(it)))
58        {
59            it = node::next_group(it);
60        }
61
62        return it;
63    }
64
65    // strong exception safety, no side effects
66    // pre: this->buckets_
67    template <class T>
68    inline BOOST_DEDUCED_TYPENAME T::node_ptr
69        hash_table<T>::find_iterator(key_type const& k) const
70    {
71        return find_iterator(this->get_bucket(this->bucket_index(k)), k);
72    }
73
74    // strong exception safety, no side effects
75    template <class T>
76    inline BOOST_DEDUCED_TYPENAME T::node_ptr*
77        hash_table<T>::find_for_erase(
78            bucket_ptr bucket, key_type const& k) const
79    {
80        node_ptr* it = &bucket->next_;
81        while(BOOST_UNORDERED_BORLAND_BOOL(*it) &&
82            !equal(k, node::get_value(*it)))
83        {
84            it = &node::next_group(*it);
85        }
86
87        return it;
88    }
89
90    ////////////////////////////////////////////////////////////////////////////
91    // Load methods
92
93    // no throw
94    template <class T>
95    std::size_t hash_table<T>::max_size() const
96    {
97        using namespace std;
98
99        // size < mlf_ * count
100        return double_to_size_t(ceil(
101                (double) this->mlf_ * this->max_bucket_count())) - 1;
102    }
103
104    // strong safety
105    template <class T>
106    inline std::size_t hash_table<T>::bucket_index(
107        key_type const& k) const
108    {
109        // hash_function can throw:
110        return this->hash_function()(k) % this->bucket_count_;
111    }
112
113
114    // no throw
115    template <class T>
116    inline std::size_t hash_table<T>::calculate_max_load()
117    {
118        using namespace std;
119
120        // From 6.3.1/13:
121        // Only resize when size >= mlf_ * count
122        return double_to_size_t(ceil((double) mlf_ * this->bucket_count_));
123    }
124
125    template <class T>
126    void hash_table<T>::max_load_factor(float z)
127    {
128        BOOST_ASSERT(z > 0);
129        mlf_ = (std::max)(z, minimum_max_load_factor);
130        this->max_load_ = this->calculate_max_load();
131    }
132
133    // no throw
134    template <class T>
135    inline std::size_t hash_table<T>::min_buckets_for_size(
136        std::size_t size) const
137    {
138        BOOST_ASSERT(this->mlf_ != 0);
139
140        using namespace std;
141
142        // From 6.3.1/13:
143        // size < mlf_ * count
144        // => count > size / mlf_
145        //
146        // Or from rehash post-condition:
147        // count > size / mlf_
148        return next_prime(double_to_size_t(floor(size / (double) mlf_)) + 1);
149    }
150
151    ////////////////////////////////////////////////////////////////////////////
152    // recompute_begin_bucket
153
154    // init_buckets
155
156    template <class T>
157    inline void hash_table<T>::init_buckets()
158    {
159        if (this->size_) {
160            this->cached_begin_bucket_ = this->buckets_;
161            while (!this->cached_begin_bucket_->next_)
162                ++this->cached_begin_bucket_;
163        } else {
164            this->cached_begin_bucket_ = this->get_bucket(this->bucket_count_);
165        }
166        this->max_load_ = calculate_max_load();
167    }
168
169    // After an erase cached_begin_bucket_ might be left pointing to
170    // an empty bucket, so this is called to update it
171    //
172    // no throw
173
174    template <class T>
175    inline void hash_table<T>::recompute_begin_bucket(bucket_ptr b)
176    {
177        BOOST_ASSERT(!(b < this->cached_begin_bucket_));
178
179        if(b == this->cached_begin_bucket_)
180        {
181            if (this->size_ != 0) {
182                while (!this->cached_begin_bucket_->next_)
183                    ++this->cached_begin_bucket_;
184            } else {
185                this->cached_begin_bucket_ =
186                    this->get_bucket(this->bucket_count_);
187            }
188        }
189    }
190
191    // This is called when a range has been erased
192    //
193    // no throw
194
195    template <class T>
196    inline void hash_table<T>::recompute_begin_bucket(
197        bucket_ptr b1, bucket_ptr b2)
198    {
199        BOOST_ASSERT(!(b1 < this->cached_begin_bucket_) && !(b2 < b1));
200        BOOST_ASSERT(BOOST_UNORDERED_BORLAND_BOOL(b2->next_));
201
202        if(b1 == this->cached_begin_bucket_ && !b1->next_)
203            this->cached_begin_bucket_ = b2;
204    }
205
206    // no throw
207    template <class T>
208    inline float hash_table<T>::load_factor() const
209    {
210        BOOST_ASSERT(this->bucket_count_ != 0);
211        return static_cast<float>(this->size_)
212            / static_cast<float>(this->bucket_count_);
213    }
214
215    ////////////////////////////////////////////////////////////////////////////
216    // Constructors
217
218    template <class T>
219    hash_table<T>::hash_table(std::size_t num_buckets,
220        hasher const& hf, key_equal const& eq, node_allocator const& a)
221      : buckets(a, next_prime(num_buckets)),
222        base(hf, eq),
223        size_(),
224        mlf_(1.0f),
225        cached_begin_bucket_(),
226        max_load_(0)
227    {
228    }
229
230    // Copy Construct with allocator
231
232    template <class T>
233    hash_table<T>::hash_table(hash_table const& x,
234        node_allocator const& a)
235      : buckets(a, x.min_buckets_for_size(x.size_)),
236        base(x),
237        size_(x.size_),
238        mlf_(x.mlf_),
239        cached_begin_bucket_(),
240        max_load_(0)
241    {
242        if(x.size_) {
243            x.copy_buckets_to(*this);
244            this->init_buckets();
245        }
246    }
247
248    // Move Construct
249
250    template <class T>
251    hash_table<T>::hash_table(hash_table& x, move_tag)
252      : buckets(x.node_alloc(), x.bucket_count_),
253        base(x),
254        size_(0),
255        mlf_(1.0f),
256        cached_begin_bucket_(),
257        max_load_(0)
258    {
259        this->partial_swap(x);
260    }
261
262    template <class T>
263    hash_table<T>::hash_table(hash_table& x,
264        node_allocator const& a, move_tag)
265      : buckets(a, x.bucket_count_),
266        base(x),
267        size_(0),
268        mlf_(x.mlf_),
269        cached_begin_bucket_(),
270        max_load_(0)
271    {
272        if(a == x.node_alloc()) {
273            this->partial_swap(x);
274        }
275        else if(x.size_) {
276            x.copy_buckets_to(*this);
277            this->size_ = x.size_;
278            this->init_buckets();
279        }
280    }
281
282    template <class T>
283    hash_table<T>& hash_table<T>::operator=(
284        hash_table const& x)
285    {
286        hash_table tmp(x, this->node_alloc());
287        this->fast_swap(tmp);
288        return *this;
289    }
290
291    ////////////////////////////////////////////////////////////////////////////
292    // Swap & Move
293   
294    // Swap
295    //
296    // Strong exception safety
297    //
298    // Can throw if hash or predicate object's copy constructor throws
299    // or if allocators are unequal.
300
301    template <class T>
302    inline void hash_table<T>::partial_swap(hash_table& x)
303    {
304        this->buckets::swap(x); // No throw
305        std::swap(this->size_, x.size_);
306        std::swap(this->mlf_, x.mlf_);
307        std::swap(this->cached_begin_bucket_, x.cached_begin_bucket_);
308        std::swap(this->max_load_, x.max_load_);
309    }
310
311    template <class T>
312    inline void hash_table<T>::fast_swap(hash_table& x)
313    {
314        // These can throw, but they only affect the function objects
315        // that aren't in use so it is strongly exception safe, via.
316        // double buffering.
317        {
318            set_hash_functions<hasher, key_equal> op1(*this, x);
319            set_hash_functions<hasher, key_equal> op2(x, *this);
320            op1.commit();
321            op2.commit();
322        }
323        this->buckets::swap(x); // No throw
324        std::swap(this->size_, x.size_);
325        std::swap(this->mlf_, x.mlf_);
326        std::swap(this->cached_begin_bucket_, x.cached_begin_bucket_);
327        std::swap(this->max_load_, x.max_load_);
328    }
329
330    template <class T>
331    inline void hash_table<T>::slow_swap(hash_table& x)
332    {
333        if(this == &x) return;
334
335        {
336            // These can throw, but they only affect the function objects
337            // that aren't in use so it is strongly exception safe, via.
338            // double buffering.
339            set_hash_functions<hasher, key_equal> op1(*this, x);
340            set_hash_functions<hasher, key_equal> op2(x, *this);
341       
342            // Create new buckets in separate hash_buckets objects
343            // which will clean up if anything throws an exception.
344            // (all can throw, but with no effect as these are new objects).
345       
346            buckets b1(this->node_alloc(), x.min_buckets_for_size(x.size_));
347            if(x.size_) x.copy_buckets_to(b1);
348       
349            buckets b2(x.node_alloc(), this->min_buckets_for_size(this->size_));
350            if(this->size_) copy_buckets_to(b2);
351       
352            // Modifying the data, so no throw from now on.
353       
354            b1.swap(*this);
355            b2.swap(x);
356            op1.commit();
357            op2.commit();
358        }
359       
360        std::swap(this->size_, x.size_);
361
362        if(this->buckets_) this->init_buckets();
363        if(x.buckets_) x.init_buckets();
364    }
365
366    template <class T>
367    void hash_table<T>::swap(hash_table& x)
368    {
369        if(this->node_alloc() == x.node_alloc()) {
370            if(this != &x) this->fast_swap(x);
371        }
372        else {
373            this->slow_swap(x);
374        }
375    }
376
377   
378    // Move
379    //
380    // Strong exception safety (might change unused function objects)
381    //
382    // Can throw if hash or predicate object's copy constructor throws
383    // or if allocators are unequal.
384
385    template <class T>
386    void hash_table<T>::move(hash_table& x)
387    {
388        // This can throw, but it only affects the function objects
389        // that aren't in use so it is strongly exception safe, via.
390        // double buffering.
391        set_hash_functions<hasher, key_equal> new_func_this(*this, x);
392
393        if(this->node_alloc() == x.node_alloc()) {
394            this->buckets::move(x); // no throw
395            this->size_ = x.size_;
396            this->cached_begin_bucket_ = x.cached_begin_bucket_;
397            this->max_load_ = x.max_load_;
398            x.size_ = 0;
399        }
400        else {
401            // Create new buckets in separate HASH_TABLE_DATA objects
402            // which will clean up if anything throws an exception.
403            // (all can throw, but with no effect as these are new objects).
404           
405            buckets b(this->node_alloc(), x.min_buckets_for_size(x.size_));
406            if(x.size_) x.copy_buckets_to(b);
407
408            // Start updating the data here, no throw from now on.
409            this->size_ = x.size_;
410            b.swap(*this);
411            this->init_buckets();
412        }
413
414        // We've made it, the rest is no throw.
415        this->mlf_ = x.mlf_;
416        new_func_this.commit();
417    }
418   
419    ////////////////////////////////////////////////////////////////////////////
420    // Reserve & Rehash
421
422    // basic exception safety
423    template <class T>
424    inline void hash_table<T>::create_for_insert(std::size_t size)
425    {
426        this->bucket_count_ = (std::max)(this->bucket_count_,
427            this->min_buckets_for_size(size));
428        this->create_buckets();
429        this->init_buckets();
430    }
431
432    // basic exception safety
433    template <class T>
434    inline bool hash_table<T>::reserve_for_insert(std::size_t size)
435    {
436        if(size >= max_load_) {
437            std::size_t num_buckets
438                = this->min_buckets_for_size((std::max)(size,
439                    this->size_ + (this->size_ >> 1)));
440            if(num_buckets != this->bucket_count_) {
441                rehash_impl(num_buckets);
442                return true;
443            }
444        }
445       
446        return false;
447    }
448
449    // if hash function throws, basic exception safety
450    // strong otherwise.
451
452    template <class T>
453    inline void hash_table<T>::rehash(std::size_t min_buckets)
454    {
455        using namespace std;
456
457        if(!this->size_) {
458            if(this->buckets_) this->delete_buckets();
459            this->bucket_count_ = next_prime(min_buckets);
460        }
461        else {
462            // no throw:
463            min_buckets = next_prime((std::max)(min_buckets,
464                    double_to_size_t(floor(this->size_ / (double) mlf_)) + 1));
465            if(min_buckets != this->bucket_count_) rehash_impl(min_buckets);
466        }
467    }
468
469    // if hash function throws, basic exception safety
470    // strong otherwise
471
472    template <class T>
473    void hash_table<T>
474        ::rehash_impl(std::size_t num_buckets)
475    {   
476        hasher const& hf = this->hash_function();
477        std::size_t size = this->size_;
478        bucket_ptr end = this->get_bucket(this->bucket_count_);
479
480        buckets dst(this->node_alloc(), num_buckets);
481        dst.create_buckets();
482
483        buckets src(this->node_alloc(), this->bucket_count_);
484        src.swap(*this);
485        this->size_ = 0;
486
487        for(bucket_ptr bucket = this->cached_begin_bucket_;
488            bucket != end; ++bucket)
489        {
490            node_ptr group = bucket->next_;
491            while(group) {
492                // Move the first group of equivalent nodes in bucket to dst.
493
494                // This next line throws iff the hash function throws.
495                bucket_ptr dst_bucket = dst.bucket_ptr_from_hash(
496                    hf(get_key_from_ptr(group)));
497
498                node_ptr& next_group = node::next_group(group);
499                bucket->next_ = next_group;
500                next_group = dst_bucket->next_;
501                dst_bucket->next_ = group;
502                group = bucket->next_;
503            }
504        }
505
506        // Swap the new nodes back into the container and setup the local
507        // variables.
508        this->size_ = size;
509        dst.swap(*this);                        // no throw
510        this->init_buckets();
511    }
512
513    ////////////////////////////////////////////////////////////////////////////
514    // copy_buckets_to
515
516    // copy_buckets_to
517    //
518    // basic excpetion safety. If an exception is thrown this will
519    // leave dst partially filled.
520
521    template <class T>
522    void hash_table<T>
523        ::copy_buckets_to(buckets& dst) const
524    {
525        BOOST_ASSERT(this->buckets_ && !dst.buckets_);
526
527        hasher const& hf = this->hash_function();
528        bucket_ptr end = this->get_bucket(this->bucket_count_);
529
530        node_constructor a(dst);
531        dst.create_buckets();
532
533        // no throw:
534        for(bucket_ptr i = this->cached_begin_bucket_; i != end; ++i) {
535            // no throw:
536            for(node_ptr it = i->next_; it;) {
537                // hash function can throw.
538                bucket_ptr dst_bucket = dst.bucket_ptr_from_hash(
539                    hf(get_key_from_ptr(it)));
540                // throws, strong
541
542                node_ptr group_end = node::next_group(it);
543
544                a.construct(node::get_value(it));
545                node_ptr n = a.release();
546                node::add_to_bucket(n, *dst_bucket);
547       
548                for(it = it->next_; it != group_end; it = it->next_) {
549                    a.construct(node::get_value(it));
550                    node::add_after_node(a.release(), n);
551                }
552            }
553        }
554    }
555
556    ////////////////////////////////////////////////////////////////////////////
557    // Misc. key methods
558
559    // strong exception safety
560
561    // count
562    //
563    // strong exception safety, no side effects
564
565    template <class T>
566    std::size_t hash_table<T>::count(key_type const& k) const
567    {
568        if(!this->size_) return 0;
569        node_ptr it = find_iterator(k); // throws, strong
570        return BOOST_UNORDERED_BORLAND_BOOL(it) ? node::group_count(it) : 0;
571    }
572
573    // find
574    //
575    // strong exception safety, no side effects
576    template <class T>
577    BOOST_DEDUCED_TYPENAME T::iterator_base
578        hash_table<T>::find(key_type const& k) const
579    {
580        if(!this->size_) return this->end();
581
582        bucket_ptr bucket = this->get_bucket(this->bucket_index(k));
583        node_ptr it = find_iterator(bucket, k);
584
585        if (BOOST_UNORDERED_BORLAND_BOOL(it))
586            return iterator_base(bucket, it);
587        else
588            return this->end();
589    }
590
591    template <class T>
592    template <class Key, class Hash, class Pred>
593    BOOST_DEDUCED_TYPENAME T::iterator_base hash_table<T>::find(Key const& k,
594        Hash const& h, Pred const& eq) const
595    {
596        if(!this->size_) return this->end();
597
598        bucket_ptr bucket = this->get_bucket(h(k) % this->bucket_count_);
599        node_ptr it = find_iterator(bucket, k, eq);
600
601        if (BOOST_UNORDERED_BORLAND_BOOL(it))
602            return iterator_base(bucket, it);
603        else
604            return this->end();
605    }
606
607    template <class T>
608    BOOST_DEDUCED_TYPENAME T::value_type&
609        hash_table<T>::at(key_type const& k) const
610    {
611        if(!this->size_)
612            boost::throw_exception(std::out_of_range("Unable to find key in unordered_map."));
613
614        bucket_ptr bucket = this->get_bucket(this->bucket_index(k));
615        node_ptr it = find_iterator(bucket, k);
616
617        if (!it)
618            boost::throw_exception(std::out_of_range("Unable to find key in unordered_map."));
619
620        return node::get_value(it);
621    }
622
623    // equal_range
624    //
625    // strong exception safety, no side effects
626    template <class T>
627    BOOST_DEDUCED_TYPENAME T::iterator_pair
628        hash_table<T>::equal_range(key_type const& k) const
629    {
630        if(!this->size_)
631            return iterator_pair(this->end(), this->end());
632
633        bucket_ptr bucket = this->get_bucket(this->bucket_index(k));
634        node_ptr it = find_iterator(bucket, k);
635        if (BOOST_UNORDERED_BORLAND_BOOL(it)) {
636            iterator_base first(iterator_base(bucket, it));
637            iterator_base second(first);
638            second.increment_bucket(node::next_group(second.node_));
639            return iterator_pair(first, second);
640        }
641        else {
642            return iterator_pair(this->end(), this->end());
643        }
644    }
645   
646    ////////////////////////////////////////////////////////////////////////////
647    // Erase methods   
648   
649    template <class T>
650    void hash_table<T>::clear()
651    {
652        if(!this->size_) return;
653
654        bucket_ptr end = this->get_bucket(this->bucket_count_);
655        for(bucket_ptr begin = this->buckets_; begin != end; ++begin) {
656            this->clear_bucket(begin);
657        }
658
659        this->size_ = 0;
660        this->cached_begin_bucket_ = end;
661    }
662
663    template <class T>
664    inline std::size_t hash_table<T>::erase_group(
665        node_ptr* it, bucket_ptr bucket)
666    {
667        node_ptr pos = *it;
668        node_ptr end = node::next_group(pos);
669        *it = end;
670        std::size_t count = this->delete_nodes(pos, end);
671        this->size_ -= count;
672        this->recompute_begin_bucket(bucket);
673        return count;
674    }
675   
676    template <class T>
677    std::size_t hash_table<T>::erase_key(key_type const& k)
678    {
679        if(!this->size_) return 0;
680   
681        // No side effects in initial section
682        bucket_ptr bucket = this->get_bucket(this->bucket_index(k));
683        node_ptr* it = this->find_for_erase(bucket, k);
684
685        // No throw.
686        return *it ? this->erase_group(it, bucket) : 0;
687    }
688
689    template <class T>
690    void hash_table<T>::erase(iterator_base r)
691    {
692        BOOST_ASSERT(r.node_);
693        --this->size_;
694        node::unlink_node(*r.bucket_, r.node_);
695        this->delete_node(r.node_);
696        // r has been invalidated but its bucket is still valid
697        this->recompute_begin_bucket(r.bucket_);
698    }
699
700    template <class T>
701    BOOST_DEDUCED_TYPENAME T::iterator_base
702        hash_table<T>::erase_return_iterator(iterator_base r)
703    {
704        BOOST_ASSERT(r.node_);
705        iterator_base next = r;
706        next.increment();
707        --this->size_;
708        node::unlink_node(*r.bucket_, r.node_);
709        this->delete_node(r.node_);
710        // r has been invalidated but its bucket is still valid
711        this->recompute_begin_bucket(r.bucket_, next.bucket_);
712        return next;
713    }
714
715    template <class T>
716    BOOST_DEDUCED_TYPENAME T::iterator_base
717        hash_table<T>::erase_range(
718            iterator_base r1, iterator_base r2)
719    {
720        if(r1 != r2)
721        {
722            BOOST_ASSERT(r1.node_);
723            if (r1.bucket_ == r2.bucket_) {
724                node::unlink_nodes(*r1.bucket_, r1.node_, r2.node_);
725                this->size_ -= this->delete_nodes(r1.node_, r2.node_);
726
727                // No need to call recompute_begin_bucket because
728                // the nodes are only deleted from one bucket, which
729                // still contains r2 after the erase.
730                 BOOST_ASSERT(r1.bucket_->next_);
731            }
732            else {
733                bucket_ptr end_bucket = r2.node_ ?
734                    r2.bucket_ : this->get_bucket(this->bucket_count_);
735                BOOST_ASSERT(r1.bucket_ < end_bucket);
736                node::unlink_nodes(*r1.bucket_, r1.node_, node_ptr());
737                this->size_ -= this->delete_nodes(r1.node_, node_ptr());
738
739                bucket_ptr i = r1.bucket_;
740                for(++i; i != end_bucket; ++i) {
741                    this->size_ -= this->delete_nodes(i->next_, node_ptr());
742                    i->next_ = node_ptr();
743                }
744
745                if(r2.node_) {
746                    node_ptr first = r2.bucket_->next_;
747                    node::unlink_nodes(*r2.bucket_, r2.node_);
748                    this->size_ -= this->delete_nodes(first, r2.node_);
749                }
750
751                // r1 has been invalidated but its bucket is still
752                // valid.
753                this->recompute_begin_bucket(r1.bucket_, end_bucket);
754            }
755        }
756
757        return r2;
758    }
759
760    template <class T>
761    BOOST_DEDUCED_TYPENAME hash_table<T>::iterator_base
762        hash_table<T>::emplace_empty_impl_with_node(
763            node_constructor& a, std::size_t size)
764    {
765        key_type const& k = get_key(a.value());
766        std::size_t hash_value = this->hash_function()(k);
767        if(this->buckets_) this->reserve_for_insert(size);
768        else this->create_for_insert(size);
769        bucket_ptr bucket = this->bucket_ptr_from_hash(hash_value);
770        node_ptr n = a.release();
771        node::add_to_bucket(n, *bucket);
772        ++this->size_;
773        this->cached_begin_bucket_ = bucket;
774        return iterator_base(bucket, n);
775    }
776}}
777
778#endif
Note: See TracBrowser for help on using the repository browser.