xref: /trunk/main/o3tl/inc/o3tl/vector_pool.hxx (revision 7ee1d29c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef INCLUDED_O3TL_VECTOR_POOL_HXX
25 #define INCLUDED_O3TL_VECTOR_POOL_HXX
26 
27 #include <sal/types.h>
28 #include <vector>
29 
30 namespace o3tl
31 {
32     namespace detail
33     {
34         template<typename ValueType, class Container> class simple_pool_impl :
35             public Container
36         {
37             typedef typename Container::value_type value_type;
38             std::ptrdiff_t mnFirstFreeIndex;
39 
40         public:
simple_pool_impl()41             simple_pool_impl() :
42                 mnFirstFreeIndex(-1)
43             {}
44 
alloc()45             std::ptrdiff_t alloc()
46             {
47                 return store(ValueType());
48             }
49 
store(const ValueType & rCopy)50             std::ptrdiff_t store(const ValueType& rCopy)
51             {
52                 if( mnFirstFreeIndex != -1 )
53                 {
54                     std::ptrdiff_t nIdx=mnFirstFreeIndex;
55                     mnFirstFreeIndex = this->at(mnFirstFreeIndex).nextFree;
56                     this->at(nIdx).value = rCopy;
57                     this->at(nIdx).nextFree = -1;
58 
59                     return nIdx;
60                 }
61                 else
62                 {
63                     this->push_back(value_type(rCopy));
64                     return this->size()-1;
65                 }
66             }
67 
free(std::ptrdiff_t nIdx)68             void free( std::ptrdiff_t nIdx )
69             {
70                 this->at(nIdx).nextFree = mnFirstFreeIndex;
71                 mnFirstFreeIndex = nIdx;
72             }
73 
get(std::ptrdiff_t nIdx) const74             const ValueType& get( std::ptrdiff_t nIdx ) const
75             {
76                 return this->operator[](nIdx).value;
77             }
get(std::ptrdiff_t nIdx)78             ValueType& get( std::ptrdiff_t nIdx )
79             {
80                 return this->operator[](nIdx).value;
81             }
82         };
83 
84         template< typename ValueType > struct struct_from_value
85         {
86             struct type
87             {
typeo3tl::detail::struct_from_value::type88                 type() :
89                     value(),
90                     nextFree(-1)
91                 {}
typeo3tl::detail::struct_from_value::type92                 explicit type( const ValueType& val ) :
93                     value(val),
94                     nextFree(-1)
95                 {}
96 
97                 ValueType      value;
98                 std::ptrdiff_t nextFree;
99             };
100         };
101     }
102 
103     /** Simple vector-based memory pool allocator
104 
105         This template can be used to provide simple pooled memory
106         allocation from a container class that adheres to the stl
107         random access container concept. Note that alloc/free works
108         with _indices_ into the container!
109 
110         @example
111         <pre>
112 vector_pool<type> myPool;
113 int nIdx=myPool.alloc();
114 myPool[nIdx] = myVal;
115  ... do stuff ...
116 myPool.free(nIdx);
117         </pre>
118      */
119     template<typename ValueType> struct vector_pool :
120         public detail::simple_pool_impl<ValueType,
121                                        std::vector<typename detail::struct_from_value<ValueType>::type > >
122     {};
123 }
124 
125 #endif /* INCLUDED_O3TL_VECTOR_POOL_HXX */
126