3/////////////////////////////////////////////////
5/////////////////////////////////////////////////
6template <typename Object, typename ObjectId>
7ObjectPool <Object, ObjectId>::ObjectPool (ObjectPool <Object, ObjectId>&& rhs)
9 WriteLock rhsLock (rhs.mMutex);
10 mIdToSlot = std::move (rhs.mIdToSlot);
11 mSlotToId = std::move (rhs.mSlotToId);
12 mObjects = std::move (rhs.mObjects);
15/////////////////////////////////////////////////
16template <typename Object, typename ObjectId>
17ObjectPool <Object, ObjectId>::ObjectPool (const ObjectPool <Object, ObjectId>& rhs)
19 WriteLock rhsLock (rhs.mMutex);
20 mIdToSlot = rhs.mIdToSlot;
21 mSlotToId = rhs.mSlotToId;
22 mObjects = rhs.mObjects;
25/////////////////////////////////////////////////
26template <typename Object, typename ObjectId>
27ObjectPool <Object, ObjectId>&
28ObjectPool <Object, ObjectId>::operator= (ObjectPool <Object, ObjectId>&& rhs)
31 WriteLock lhsLock (mMutex, std::defer_lock);
32 WriteLock rhsLock (rhs.mMutex, std::defer_lock);
33 std::lock (lhsLock, rhsLock);
34 mIdToSlot = std::move (rhs.mIdToSlot);
35 mSlotToId = std::move (rhs.mSlotToId);
36 mObjects = std::move (rhs.mObjects);
41/////////////////////////////////////////////////
42template <typename Object, typename ObjectId>
43ObjectPool <Object, ObjectId>&
44ObjectPool <Object, ObjectId>::operator= (const ObjectPool <Object, ObjectId>& rhs)
47 WriteLock lhsLock (mMutex, std::defer_lock);
48 ReadLock rhsLock (rhs.mMutex, std::defer_lock);
49 std::lock (lhsLock, rhsLock);
50 mIdToSlot = rhs.mIdToSlot;
51 mSlotToId = rhs.mSlotToId;
52 mObjects = rhs.mObjects;
58/////////////////////////////////////////////////
60/////////////////////////////////////////////////
61template <typename Object, typename ObjectId>
62Object& ObjectPool <Object, ObjectId>::add (Object&& object, const ObjectId& id)
64 // quit if id exist in pool
65 if (has (id)) return mObjects.back ();
67 // add object in pool and return it
69 WriteLock lock (mMutex);
70 mObjects.emplace_back (std::forward <Object> (object));
71 return mObjects.back ();
74/////////////////////////////////////////////////
75template <typename Object, typename ObjectId>
76Object& ObjectPool <Object, ObjectId>::add (const Object& object, const ObjectId& id)
78 // quit if id exist in pool
79 if (has (id)) return mObjects.back ();
81 // add object in pool and return it
83 WriteLock lock (mMutex);
84 mObjects.push_back (object);
85 return mObjects.back ();
88/////////////////////////////////////////////////
89template <typename Object, typename ObjectId>
90template <typename... ObjectArgs>
91Object& ObjectPool <Object, ObjectId>::emplace (const ObjectId& id, ObjectArgs&&... constructorArgs)
93 // quit if id exist in pool
94 if (has (id)) return mObjects.back ();
96 // emplace object in pool and return it
98 WriteLock lock (mMutex);
99 mObjects.emplace_back (std::forward <ObjectArgs> (constructorArgs)...);
100 return mObjects.back ();
103/////////////////////////////////////////////////
104template <typename Object, typename ObjectId>
105void ObjectPool <Object, ObjectId>::remove (const ObjectId& object)
107 // quit if id does not exist in pool
108 if (!has (object)) return;
110 // get corresponding slot of object to be removed
111 WriteLock lock (mMutex);
112 const auto slot = mIdToSlot [object];
113 // swap object to be removed with the last one and removes it
114 std::swap (mObjects [slot], mObjects.back ());
115 mObjects.pop_back ();
117 // store new slot of the swapped last object
118 const auto lastObject = mSlotToId.back ();
119 mIdToSlot [lastObject] = slot;
120 mSlotToId [slot] = lastObject;
121 // erase id and slot of the removed object
122 mIdToSlot.erase (object);
123 mSlotToId.pop_back ();
126/////////////////////////////////////////////////
127template <typename Object, typename ObjectId>
128void ObjectPool <Object, ObjectId>::reserve (const size_t amount)
130 WriteLock lock (mMutex);
131 mIdToSlot.reserve (amount);
132 mSlotToId.reserve (amount);
133 mObjects.reserve (amount);
136/////////////////////////////////////////////////
137template <typename Object, typename ObjectId>
138void ObjectPool <Object, ObjectId>::clear ()
140 WriteLock lock (mMutex);
146/////////////////////////////////////////////////
147template <typename Object, typename ObjectId>
148bool ObjectPool <Object, ObjectId>::has (const ObjectId& object) const
150 ReadLock lock (mMutex);
151 return mIdToSlot.find (object) != std::cend (mIdToSlot);
154/////////////////////////////////////////////////
155template <typename Object, typename ObjectId>
156bool ObjectPool <Object, ObjectId>::empty () const
158 ReadLock lock (mMutex);
159 return mObjects.empty ();
162/////////////////////////////////////////////////
163template <typename Object, typename ObjectId>
164Object& ObjectPool <Object, ObjectId>::get (const ObjectId& object)
166 ReadLock lock (mMutex);
167 return mObjects [mIdToSlot [object]];
170/////////////////////////////////////////////////
171template <typename Object, typename ObjectId>
172const Object& ObjectPool <Object, ObjectId>::get (const ObjectId& object) const
174 ReadLock lock (mMutex);
175 return mObjects [mIdToSlot.at (object)];
178/////////////////////////////////////////////////
179template <typename Object, typename ObjectId>
180void ObjectPool <Object, ObjectId>::changeId (const ObjectId& oldId, const ObjectId& newId)
182 WriteLock lock (mMutex);
183 const auto slot = mIdToSlot [oldId];
184 mIdToSlot [newId] = slot;
185 mSlotToId [slot] = newId;
186 mIdToSlot.erase (oldId);
189/////////////////////////////////////////////////
190template <typename Object, typename ObjectId>
191std::vector <ObjectId>
192ObjectPool <Object, ObjectId>::ids () const
194 WriteLock lock (mMutex);
195 auto list = std::vector <ObjectId> ();
196 list.reserve (mIdToSlot.size ());
197 for (const auto& idAndSlot : mIdToSlot) {
198 list.push_back (idAndSlot.first);
203/////////////////////////////////////////////////
204template <typename Object, typename ObjectId>
205size_t ObjectPool <Object, ObjectId>::size () const
207 ReadLock lock (mMutex);
208 return mObjects.size ();
211/////////////////////////////////////////////////
212template <typename Object, typename ObjectId>
213void ObjectPool <Object, ObjectId>::trackSlot (const ObjectId& id)
215 // compute slot and keep track of it and of id
216 WriteLock lock (mMutex);
217 mIdToSlot [id] = mSlotToId.size ();
218 mSlotToId.push_back (id);