bsl_poolalloc.h 4.5 KB
Newer Older
W
wangguibao 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
/***************************************************************************
 * 
 * Copyright (c) 2008 Baidu.com, Inc. All Rights Reserved
 * $Id: bsl_poolalloc.h,v 1.7 2009/06/15 06:29:04 chenxm Exp $ 
 * 
 **************************************************************************/
 
 
 
/**
 * @file bsl_poolalloc.h
 * @author xiaowei(com@baidu.com)
 * @date 2008/12/08 18:30:29
 * @version $Revision: 1.7 $ 
 * @brief 
 *  
 **/


#ifndef  __BSL_POOLALLOC_H_
#define  __BSL_POOLALLOC_H_
#include <bsl/exception/bsl_exception.h>
#include "bsl_pool.h"
#include <cstddef>

namespace bsl
{

    template<typename _Tp>
        class pool_allocator;

    /**
    * @brief pool_allocator对void的特化
    *  
    *  没有分配内存作用,只可以rebind到其它类型
    */
    template<>
        class pool_allocator<void>
        {
        public:
            typedef size_t      size_type;
            typedef ptrdiff_t   difference_type;
            typedef void*       pointer;
            typedef const void* const_pointer;
            typedef void        value_type;

            template<typename _Tp1>
                friend class pool_allocator;

            template<typename _Tp1>
                struct rebind
                { typedef pool_allocator<_Tp1> other; };

            pool_allocator() throw()
                :_p_pool(NULL)  { }

            pool_allocator(mempool *p_pool) throw() 
                :_p_pool(p_pool) { }

            pool_allocator(const pool_allocator & a) throw()
                :_p_pool(a._p_pool){ }

            template<typename _Tp1>
                pool_allocator( const pool_allocator<_Tp1>& a ) throw()
                :_p_pool(a._p_pool){ }

            ~pool_allocator() throw() { }
        private:
            mempool *_p_pool;
            
        };

    template<typename _Tp>
        class pool_allocator
        {
        public:
            typedef size_t     size_type;
            typedef ptrdiff_t  difference_type;
            typedef _Tp*       pointer;
            typedef const _Tp* const_pointer;
            typedef _Tp&       reference;
            typedef const _Tp& const_reference;
            typedef _Tp        value_type;

            template<typename _Tp1>
                friend class pool_allocator;

            template<typename _Tp1>
                struct rebind { typedef pool_allocator<_Tp1> other; };

            pool_allocator() throw()
                :_p_pool(NULL)  { }

            pool_allocator(mempool *p_pool) throw() 
                :_p_pool(p_pool) { }

            pool_allocator(const pool_allocator & a) throw()
                :_p_pool(a._p_pool){ }

            template<typename _Tp1>
                pool_allocator( const pool_allocator<_Tp1>& a ) throw()
                :_p_pool(a._p_pool){ }

            ~pool_allocator() throw() { }

            pointer
                address(reference __x) const { return &__x; }

            const_pointer
                address(const_reference __x) const { return &__x; }

            pointer
                allocate(size_type __n, const void* = 0)
                {
                    size_t  size_  = __n * sizeof(_Tp);
                    pointer __ret = static_cast<_Tp*>( _p_pool ? _p_pool->malloc(size_) : malloc(size_) );
                    if (!__ret){
                        throw bsl::BadAllocException() << BSL_EARG << "size["<<size_<<"] _p_pool["<<_p_pool<<"]";
                    }
                    return __ret;
                }

            // __p is not permitted to be a null pointer.
            void
                deallocate(pointer __p, size_type size_) 
                { 
                    if ( _p_pool ){
                        _p_pool->free (static_cast<void *>(__p), sizeof(_Tp) * size_);
                    }else{
                        free( __p );
                    }
                }

            size_type
                max_size() const throw() { 
                    return size_t(-1) / sizeof(_Tp); 
                }

            void 
                construct(pointer __p, const _Tp& __val) 
                { ::new(__p) value_type(__val); }

            void 
                destroy(pointer __p) { __p->~_Tp(); }

            bool
                operator==(const pool_allocator& other) const  { 
                    return _p_pool == other._p_pool;
                }

            bool
                operator!=(const pool_allocator& other) const  { 
                    return _p_pool != other._p_pool;
                }

        private:
            mempool *_p_pool;
        };


}





#endif  //__BSL_POOLALLOC_H_

/* vim: set ts=4 sw=4 sts=4 tw=100 */