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