Coverage Report

Created: 2025-06-13 06:12

/src/resiprocate/rutil/StlPoolAllocator.hxx
Line
Count
Source
1
#ifndef StlPoolAllocator_Include_Guard
2
#define StlPoolAllocator_Include_Guard
3
4
#include <limits>
5
#include <memory>
6
#include <stddef.h>
7
8
// .bwc. gcc 4.2 and above support stateful allocators. I don't know about other 
9
// compilers; if you do, add them here please.
10
#if ( (__GNUC__ == 4) && (__GNUC_MINOR__ >= 2) ) || ( __GNUC__ > 4 )
11
#define RESIP_HAS_STATEFUL_ALLOCATOR_SUPPORT
12
#endif
13
14
#ifdef max  // Max is defined under WIN32 and conflicts with std::numeric_limits<size_type>::max use below
15
#undef max
16
#endif
17
18
namespace resip
19
{
20
/**
21
   A dirt-simple lightweight stl pool allocator meant for use in short-lifetime 
22
   objects. This will pool-allocate at most S bytes, after which no further pool
23
   allocation will be performed, and fallback to the system new/delete will be 
24
   used (deallocating a pool allocated object will _not_ free up room in the 
25
   pool).
26
*/
27
template<typename T, typename P>
28
class StlPoolAllocator
29
{
30
   public:
31
      typedef T value_type;
32
      typedef value_type* pointer;
33
      typedef const value_type* const_pointer;
34
      typedef value_type& reference;
35
      typedef const value_type& const_reference;
36
      typedef size_t size_type;
37
      typedef ptrdiff_t difference_type;
38
39
#ifdef RESIP_HAS_STATEFUL_ALLOCATOR_SUPPORT
40
      explicit StlPoolAllocator(P* pool=0) :
41
411k
         mPool(pool){}
resip::StlPoolAllocator<resip::Parameter*, resip::PoolBase>::StlPoolAllocator(resip::PoolBase*)
Line
Count
Source
41
366k
         mPool(pool){}
resip::StlPoolAllocator<resip::ParserContainerBase::HeaderKit, resip::PoolBase>::StlPoolAllocator(resip::PoolBase*)
Line
Count
Source
41
267
         mPool(pool){}
resip::StlPoolAllocator<resip::HeaderFieldValue, resip::PoolBase>::StlPoolAllocator(resip::PoolBase*)
Line
Count
Source
41
25.0k
         mPool(pool){}
resip::StlPoolAllocator<resip::HeaderFieldValueList*, resip::PoolBase>::StlPoolAllocator(resip::PoolBase*)
Line
Count
Source
41
9.51k
         mPool(pool){}
resip::StlPoolAllocator<std::__1::pair<resip::Data, resip::HeaderFieldValueList*>, resip::PoolBase>::StlPoolAllocator(resip::PoolBase*)
Line
Count
Source
41
9.51k
         mPool(pool){}
42
      StlPoolAllocator(const StlPoolAllocator& other) :
43
438k
         mPool(other.mPool){}
resip::StlPoolAllocator<resip::Parameter*, resip::PoolBase>::StlPoolAllocator(resip::StlPoolAllocator<resip::Parameter*, resip::PoolBase> const&)
Line
Count
Source
43
366k
         mPool(other.mPool){}
resip::StlPoolAllocator<resip::ParserContainerBase::HeaderKit, resip::PoolBase>::StlPoolAllocator(resip::StlPoolAllocator<resip::ParserContainerBase::HeaderKit, resip::PoolBase> const&)
Line
Count
Source
43
267
         mPool(other.mPool){}
resip::StlPoolAllocator<resip::HeaderFieldValue, resip::PoolBase>::StlPoolAllocator(resip::StlPoolAllocator<resip::HeaderFieldValue, resip::PoolBase> const&)
Line
Count
Source
43
25.0k
         mPool(other.mPool){}
resip::StlPoolAllocator<resip::HeaderFieldValueList*, resip::PoolBase>::StlPoolAllocator(resip::StlPoolAllocator<resip::HeaderFieldValueList*, resip::PoolBase> const&)
Line
Count
Source
43
9.51k
         mPool(other.mPool){}
resip::StlPoolAllocator<std::__1::__list_node<std::__1::pair<resip::Data, resip::HeaderFieldValueList*>, void*>, resip::PoolBase>::StlPoolAllocator(resip::StlPoolAllocator<std::__1::__list_node<std::__1::pair<resip::Data, resip::HeaderFieldValueList*>, void*>, resip::PoolBase> const&)
Line
Count
Source
43
36.9k
         mPool(other.mPool){}
44
      StlPoolAllocator& operator=(const StlPoolAllocator& rhs)
45
      {
46
         if (&rhs != this)
47
         {
48
            mPool=rhs.mPool;
49
         }
50
         return *this;
51
      }
52
#else
53
      // Disable pool allocation if stateful allocators are not supported by the 
54
      // STL
55
      explicit StlPoolAllocator(P* pool=0) :
56
         mPool(0){}
57
      StlPoolAllocator(const StlPoolAllocator& other) :
58
         mPool(0){}
59
      StlPoolAllocator& operator=(const StlPoolAllocator& rhs)
60
      {
61
         return *this;
62
      }
63
#endif
64
65
66
      template<typename U>
67
      StlPoolAllocator(const StlPoolAllocator<U,P>& other) :
68
9.51k
         mPool(other.mPool){}
69
70
858k
      ~StlPoolAllocator(){}
resip::StlPoolAllocator<resip::Parameter*, resip::PoolBase>::~StlPoolAllocator()
Line
Count
Source
70
733k
      ~StlPoolAllocator(){}
resip::StlPoolAllocator<resip::ParserContainerBase::HeaderKit, resip::PoolBase>::~StlPoolAllocator()
Line
Count
Source
70
534
      ~StlPoolAllocator(){}
resip::StlPoolAllocator<std::__1::__list_node<std::__1::pair<resip::Data, resip::HeaderFieldValueList*>, void*>, resip::PoolBase>::~StlPoolAllocator()
Line
Count
Source
70
46.4k
      ~StlPoolAllocator(){}
resip::StlPoolAllocator<resip::HeaderFieldValue, resip::PoolBase>::~StlPoolAllocator()
Line
Count
Source
70
50.0k
      ~StlPoolAllocator(){}
resip::StlPoolAllocator<resip::HeaderFieldValueList*, resip::PoolBase>::~StlPoolAllocator()
Line
Count
Source
70
19.0k
      ~StlPoolAllocator(){}
resip::StlPoolAllocator<std::__1::pair<resip::Data, resip::HeaderFieldValueList*>, resip::PoolBase>::~StlPoolAllocator()
Line
Count
Source
70
9.51k
      ~StlPoolAllocator(){}
71
72
73
      template<typename U>
74
      struct rebind
75
      {
76
         typedef StlPoolAllocator<U, P> other;
77
      };
78
79
      pointer address(reference ref) const
80
      {
81
         return &ref;
82
      }
83
84
      const_pointer address(const_reference ref) const
85
      {
86
         return &ref;
87
      }
88
89
      pointer allocate(size_type n, const void* hint=0)
90
74.4k
      {
91
74.4k
         return (pointer)(allocate_raw(n*sizeof(T)));
92
74.4k
      }
resip::StlPoolAllocator<resip::HeaderFieldValue, resip::PoolBase>::allocate(unsigned long, void const*)
Line
Count
Source
90
21.7k
      {
91
21.7k
         return (pointer)(allocate_raw(n*sizeof(T)));
92
21.7k
      }
resip::StlPoolAllocator<resip::ParserContainerBase::HeaderKit, resip::PoolBase>::allocate(unsigned long, void const*)
Line
Count
Source
90
267
      {
91
267
         return (pointer)(allocate_raw(n*sizeof(T)));
92
267
      }
resip::StlPoolAllocator<resip::Parameter*, resip::PoolBase>::allocate(unsigned long, void const*)
Line
Count
Source
90
29.0k
      {
91
29.0k
         return (pointer)(allocate_raw(n*sizeof(T)));
92
29.0k
      }
resip::StlPoolAllocator<resip::HeaderFieldValueList*, resip::PoolBase>::allocate(unsigned long, void const*)
Line
Count
Source
90
9.56k
      {
91
9.56k
         return (pointer)(allocate_raw(n*sizeof(T)));
92
9.56k
      }
resip::StlPoolAllocator<std::__1::__list_node<std::__1::pair<resip::Data, resip::HeaderFieldValueList*>, void*>, resip::PoolBase>::allocate(unsigned long, void const*)
Line
Count
Source
90
13.7k
      {
91
13.7k
         return (pointer)(allocate_raw(n*sizeof(T)));
92
13.7k
      }
93
94
      void deallocate(pointer ptr, size_type n)
95
74.4k
      {
96
74.4k
         deallocate_raw((void*)ptr);
97
74.4k
      }
resip::StlPoolAllocator<resip::HeaderFieldValue, resip::PoolBase>::deallocate(resip::HeaderFieldValue*, unsigned long)
Line
Count
Source
95
21.7k
      {
96
21.7k
         deallocate_raw((void*)ptr);
97
21.7k
      }
resip::StlPoolAllocator<resip::ParserContainerBase::HeaderKit, resip::PoolBase>::deallocate(resip::ParserContainerBase::HeaderKit*, unsigned long)
Line
Count
Source
95
267
      {
96
267
         deallocate_raw((void*)ptr);
97
267
      }
resip::StlPoolAllocator<resip::Parameter*, resip::PoolBase>::deallocate(resip::Parameter**, unsigned long)
Line
Count
Source
95
29.0k
      {
96
29.0k
         deallocate_raw((void*)ptr);
97
29.0k
      }
resip::StlPoolAllocator<std::__1::__list_node<std::__1::pair<resip::Data, resip::HeaderFieldValueList*>, void*>, resip::PoolBase>::deallocate(std::__1::__list_node<std::__1::pair<resip::Data, resip::HeaderFieldValueList*>, void*>*, unsigned long)
Line
Count
Source
95
13.7k
      {
96
13.7k
         deallocate_raw((void*)ptr);
97
13.7k
      }
resip::StlPoolAllocator<resip::HeaderFieldValueList*, resip::PoolBase>::deallocate(resip::HeaderFieldValueList**, unsigned long)
Line
Count
Source
95
9.56k
      {
96
9.56k
         deallocate_raw((void*)ptr);
97
9.56k
      }
98
99
      inline void* allocate_raw(size_type bytes)
100
74.4k
      {
101
74.4k
         if(mPool)
102
45.7k
         {
103
45.7k
            return mPool->allocate(bytes);
104
45.7k
         }
105
28.7k
         return ::operator new(bytes);
106
74.4k
      }
resip::StlPoolAllocator<resip::HeaderFieldValue, resip::PoolBase>::allocate_raw(unsigned long)
Line
Count
Source
100
21.7k
      {
101
21.7k
         if(mPool)
102
21.7k
         {
103
21.7k
            return mPool->allocate(bytes);
104
21.7k
         }
105
0
         return ::operator new(bytes);
106
21.7k
      }
resip::StlPoolAllocator<resip::ParserContainerBase::HeaderKit, resip::PoolBase>::allocate_raw(unsigned long)
Line
Count
Source
100
267
      {
101
267
         if(mPool)
102
267
         {
103
267
            return mPool->allocate(bytes);
104
267
         }
105
0
         return ::operator new(bytes);
106
267
      }
resip::StlPoolAllocator<resip::Parameter*, resip::PoolBase>::allocate_raw(unsigned long)
Line
Count
Source
100
29.0k
      {
101
29.0k
         if(mPool)
102
392
         {
103
392
            return mPool->allocate(bytes);
104
392
         }
105
28.7k
         return ::operator new(bytes);
106
29.0k
      }
resip::StlPoolAllocator<resip::HeaderFieldValueList*, resip::PoolBase>::allocate_raw(unsigned long)
Line
Count
Source
100
9.56k
      {
101
9.56k
         if(mPool)
102
9.56k
         {
103
9.56k
            return mPool->allocate(bytes);
104
9.56k
         }
105
0
         return ::operator new(bytes);
106
9.56k
      }
resip::StlPoolAllocator<std::__1::__list_node<std::__1::pair<resip::Data, resip::HeaderFieldValueList*>, void*>, resip::PoolBase>::allocate_raw(unsigned long)
Line
Count
Source
100
13.7k
      {
101
13.7k
         if(mPool)
102
13.7k
         {
103
13.7k
            return mPool->allocate(bytes);
104
13.7k
         }
105
0
         return ::operator new(bytes);
106
13.7k
      }
107
108
      void deallocate_raw(void* ptr)
109
74.4k
      {
110
74.4k
         if(mPool)
111
45.7k
         {
112
45.7k
            mPool->deallocate(ptr);
113
45.7k
            return;
114
45.7k
         }
115
28.7k
         ::operator delete(ptr);
116
28.7k
      }
resip::StlPoolAllocator<resip::HeaderFieldValue, resip::PoolBase>::deallocate_raw(void*)
Line
Count
Source
109
21.7k
      {
110
21.7k
         if(mPool)
111
21.7k
         {
112
21.7k
            mPool->deallocate(ptr);
113
21.7k
            return;
114
21.7k
         }
115
0
         ::operator delete(ptr);
116
0
      }
resip::StlPoolAllocator<resip::ParserContainerBase::HeaderKit, resip::PoolBase>::deallocate_raw(void*)
Line
Count
Source
109
267
      {
110
267
         if(mPool)
111
267
         {
112
267
            mPool->deallocate(ptr);
113
267
            return;
114
267
         }
115
0
         ::operator delete(ptr);
116
0
      }
resip::StlPoolAllocator<resip::Parameter*, resip::PoolBase>::deallocate_raw(void*)
Line
Count
Source
109
29.0k
      {
110
29.0k
         if(mPool)
111
392
         {
112
392
            mPool->deallocate(ptr);
113
392
            return;
114
392
         }
115
28.7k
         ::operator delete(ptr);
116
28.7k
      }
resip::StlPoolAllocator<std::__1::__list_node<std::__1::pair<resip::Data, resip::HeaderFieldValueList*>, void*>, resip::PoolBase>::deallocate_raw(void*)
Line
Count
Source
109
13.7k
      {
110
13.7k
         if(mPool)
111
13.7k
         {
112
13.7k
            mPool->deallocate(ptr);
113
13.7k
            return;
114
13.7k
         }
115
0
         ::operator delete(ptr);
116
0
      }
resip::StlPoolAllocator<resip::HeaderFieldValueList*, resip::PoolBase>::deallocate_raw(void*)
Line
Count
Source
109
9.56k
      {
110
9.56k
         if(mPool)
111
9.56k
         {
112
9.56k
            mPool->deallocate(ptr);
113
9.56k
            return;
114
9.56k
         }
115
0
         ::operator delete(ptr);
116
0
      }
117
118
      size_type max_size() const
119
60.6k
      {
120
60.6k
         if(mPool)
121
31.9k
         {
122
31.9k
            return mPool->max_size();
123
31.9k
         }
124
28.7k
         return std::numeric_limits<size_type>::max()/sizeof(T);
125
60.6k
      }
resip::StlPoolAllocator<resip::HeaderFieldValue, resip::PoolBase>::max_size() const
Line
Count
Source
119
21.7k
      {
120
21.7k
         if(mPool)
121
21.7k
         {
122
21.7k
            return mPool->max_size();
123
21.7k
         }
124
0
         return std::numeric_limits<size_type>::max()/sizeof(T);
125
21.7k
      }
resip::StlPoolAllocator<resip::ParserContainerBase::HeaderKit, resip::PoolBase>::max_size() const
Line
Count
Source
119
267
      {
120
267
         if(mPool)
121
267
         {
122
267
            return mPool->max_size();
123
267
         }
124
0
         return std::numeric_limits<size_type>::max()/sizeof(T);
125
267
      }
resip::StlPoolAllocator<resip::Parameter*, resip::PoolBase>::max_size() const
Line
Count
Source
119
29.0k
      {
120
29.0k
         if(mPool)
121
392
         {
122
392
            return mPool->max_size();
123
392
         }
124
28.7k
         return std::numeric_limits<size_type>::max()/sizeof(T);
125
29.0k
      }
resip::StlPoolAllocator<resip::HeaderFieldValueList*, resip::PoolBase>::max_size() const
Line
Count
Source
119
9.56k
      {
120
9.56k
         if(mPool)
121
9.56k
         {
122
9.56k
            return mPool->max_size();
123
9.56k
         }
124
0
         return std::numeric_limits<size_type>::max()/sizeof(T);
125
9.56k
      }
126
127
      size_type max_size(size_type _sz) const
128
      {
129
         if(mPool)
130
         {
131
            return mPool->max_size();
132
         }
133
         return std::numeric_limits<size_type>::max()/_sz;
134
      }
135
136
      void construct(pointer p, const_reference orig)
137
2.57M
      {
138
2.57M
         new (p) T(orig);
139
2.57M
      }
resip::StlPoolAllocator<resip::HeaderFieldValue, resip::PoolBase>::construct(resip::HeaderFieldValue*, resip::HeaderFieldValue const&)
Line
Count
Source
137
2.45M
      {
138
2.45M
         new (p) T(orig);
139
2.45M
      }
resip::StlPoolAllocator<resip::ParserContainerBase::HeaderKit, resip::PoolBase>::construct(resip::ParserContainerBase::HeaderKit*, resip::ParserContainerBase::HeaderKit const&)
Line
Count
Source
137
267
      {
138
267
         new (p) T(orig);
139
267
      }
resip::StlPoolAllocator<resip::Parameter*, resip::PoolBase>::construct(resip::Parameter**, resip::Parameter* const&)
Line
Count
Source
137
104k
      {
138
104k
         new (p) T(orig);
139
104k
      }
resip::StlPoolAllocator<resip::HeaderFieldValueList*, resip::PoolBase>::construct(resip::HeaderFieldValueList**, resip::HeaderFieldValueList* const&)
Line
Count
Source
137
12.0k
      {
138
12.0k
         new (p) T(orig);
139
12.0k
      }
140
141
      void destroy(pointer ptr)
142
2.57M
      {
143
2.57M
         ptr->~T();
144
2.57M
      }
resip::StlPoolAllocator<resip::HeaderFieldValue, resip::PoolBase>::destroy(resip::HeaderFieldValue*)
Line
Count
Source
142
2.45M
      {
143
2.45M
         ptr->~T();
144
2.45M
      }
resip::StlPoolAllocator<resip::ParserContainerBase::HeaderKit, resip::PoolBase>::destroy(resip::ParserContainerBase::HeaderKit*)
Line
Count
Source
142
267
      {
143
267
         ptr->~T();
144
267
      }
resip::StlPoolAllocator<resip::Parameter*, resip::PoolBase>::destroy(resip::Parameter**)
Line
Count
Source
142
104k
      {
143
104k
         ptr->~T();
144
104k
      }
resip::StlPoolAllocator<resip::HeaderFieldValueList*, resip::PoolBase>::destroy(resip::HeaderFieldValueList**)
Line
Count
Source
142
12.0k
      {
143
12.0k
         ptr->~T();
144
12.0k
      }
145
146
      bool operator==(const StlPoolAllocator& rhs) const
147
      {
148
         return mPool == rhs.mPool;
149
      }
150
151
      bool operator!=(const StlPoolAllocator& rhs) const
152
      {
153
         return mPool != rhs.mPool;
154
      }
155
156
      P* mPool;
157
};
158
159
}
160
161
#endif
162
163
164
/* ====================================================================
165
 * The Vovida Software License, Version 1.0 
166
 * 
167
 * Redistribution and use in source and binary forms, with or without
168
 * modification, are permitted provided that the following conditions
169
 * are met:
170
 * 
171
 * 1. Redistributions of source code must retain the above copyright
172
 *    notice, this list of conditions and the following disclaimer.
173
 * 
174
 * 2. Redistributions in binary form must reproduce the above copyright
175
 *    notice, this list of conditions and the following disclaimer in
176
 *    the documentation and/or other materials provided with the
177
 *    distribution.
178
 * 
179
 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
180
 *    and "Vovida Open Communication Application Library (VOCAL)" must
181
 *    not be used to endorse or promote products derived from this
182
 *    software without prior written permission. For written
183
 *    permission, please contact vocal@vovida.org.
184
 *
185
 * 4. Products derived from this software may not be called "VOCAL", nor
186
 *    may "VOCAL" appear in their name, without prior written
187
 *    permission of Vovida Networks, Inc.
188
 * 
189
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
190
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
191
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
192
 * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
193
 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
194
 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
195
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
196
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
197
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
198
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
199
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
200
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
201
 * DAMAGE.
202
 * 
203
 * ====================================================================
204
 * 
205
 * This software consists of voluntary contributions made by Vovida
206
 * Networks, Inc. and many individuals on behalf of Vovida Networks,
207
 * Inc.  For more information on Vovida Networks, Inc., please see
208
 * <http://www.vovida.org/>.
209
 *
210
 */