2 * Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration.
5 * @file AthContainers/tools/JaggedVecVector.icc
6 * @author scott snyder <snyder@bnl.gov>
8 * @brief Implementation of @c IAuxTypeVector for @c JaggedVecElt types.
12 #include "AthContainers/AuxTypeRegistry.h"
20 * @param auxid The auxid of the variable this vector represents.
21 * @param vecPtr Pointer to the object.
22 * @param linkedVec Interface for the linked vector of DataLinks.
23 * @param ownFlag If true, take ownership of the object.
25 template <class T, class ALLOC>
26 JaggedVecVectorHolder<T, ALLOC>::JaggedVecVectorHolder
29 IAuxTypeVector* linkedVec,
31 : Base (auxid, vecPtr, ownFlag, false),
32 m_linkedVec (linkedVec)
38 * @brief Change the size of the vector.
39 * @param sz The new vector size.
40 * Returns true if it is known that iterators have not been invalidated;
43 template <class T, class ALLOC>
45 bool JaggedVecVectorHolder<T, ALLOC>::resize (size_t sz)
48 vector_type& vec = this->vec();
50 if (sz < vec.size()) {
51 size_t payload_sz = sz > 0 ? vec[sz-1].end() : 0;
52 valid = m_linkedVec->resize (payload_sz);
54 else if (vec.size() > 0) {
55 size_t payload_sz = vec.back().end();
56 zero = Elt (payload_sz);
58 const void* orig = vec.data();
59 vec.resize (sz, zero);
60 this->storeDataSpan();
61 return valid && vec.data() == orig;
66 * @brief Shift the elements of the vector.
67 * @param pos The starting index for the shift.
68 * @param offs The (signed) amount of the shift.
70 * This operation shifts the elements in the vectors for all
71 * aux data items, to implement an insertion or deletion.
72 * @c offs may be either positive or negative.
74 * If @c offs is positive, then the container is growing.
75 * The container size should be increased by @c offs,
76 * the element at @c pos moved to @c pos + @c offs,
77 * and similarly for following elements.
78 * The elements between @c pos and @c pos + @c offs should
79 * be default-initialized.
81 * If @c offs is negative, then the container is shrinking.
82 * The element at @c pos should be moved to @c pos + @c offs,
83 * and similarly for following elements.
84 * The container should then be shrunk by @c -offs elements
85 * (running destructors as appropriate).
87 * Returns true if it is known that iterators have not been invalidated;
88 * false otherwise. (Will always return false when increasing the size
89 * of an empty container.)
91 template <class T, class ALLOC>
92 bool JaggedVecVectorHolder<T, ALLOC>::shift (size_t pos, ptrdiff_t offs)
94 vector_type& vec = this->vec();
96 if (-offs > static_cast<ptrdiff_t>(pos)) offs = -pos;
97 size_t ppos = pos < vec.size() ? vec[pos].begin(pos) : m_linkedVec->size();
98 ptrdiff_t poffs = - (ppos - vec[pos+offs].begin(pos+offs));
99 m_linkedVec->shift (ppos, poffs);
100 vec.erase (vec.begin() + pos+offs, vec.begin() + pos);
101 std::for_each (vec.begin() + pos+offs, vec.end(), Shift (poffs));
102 this->storeDataSpan();
106 const void* orig = vec.data();
107 size_t oldsz = vec.size();
110 index_type end = vec.back().end();
113 // Add to the end, zero-filled.
114 vec.resize (vec.size() + offs, zero);
116 // Shift existing elements. If we're just extending,
117 // then we can skip this.
118 std::copy (vec.rbegin() + offs,
119 vec.rbegin() + (offs+oldsz-pos),
125 index_type end = vec[pos-1].end();
128 std::fill_n (vec.begin() + pos, offs, zero);
130 this->storeDataSpan();
131 return vec.data() == orig;
138 * @brief Insert elements into the vector via move semantics.
139 * @param pos The starting index of the insertion.
140 * @param src Start of the vector containing the range of elements to insert.
141 * @param src_pos Position of the first element to insert.
142 * @param src_n Number of elements to insert.
143 * @param srcStore The source store.
145 * @c beg and @c end define a range of container elements, with length
146 * @c len defined by the difference of the pointers divided by the
149 * The size of the container will be increased by @c len, with the elements
150 * starting at @c pos copied to @c pos+len.
152 * The contents of the source range will then be moved to our vector
153 * starting at @c pos. This will be done via move semantics if possible;
154 * otherwise, it will be done with a copy.
156 * Returns true if it is known that the vector's memory did not move,
159 template <class T, class ALLOC>
160 bool JaggedVecVectorHolder<T, ALLOC>::insertMove
161 (size_t pos, void* src, size_t src_pos, size_t src_n, IAuxStore& srcStore)
163 if (src_n <= 0) return true;
164 element_type* srcp = reinterpret_cast<element_type*> (src);
165 element_type* beg = srcp + src_pos;
166 element_type* end = beg + src_n;
168 vector_type& vec = this->vec();
169 const element_type* orig = vec.data();
170 vec.insert (vec.begin() + pos, beg, end);
171 size_t begidx = srcp[src_pos].begin(src_pos);
172 size_t npayload = beg[src_n-1].end() - begidx;
173 size_t ppos = vec[pos].begin(pos);
174 IAuxTypeVector* srcPayloadVec = srcStore.linkedVector (this->auxid());
175 T* srcPayload = reinterpret_cast<T*> (srcPayloadVec->toPtr());
176 bool pflag = m_linkedVec->insertMove (ppos,
181 std::for_each (vec.begin() + pos, vec.begin() + pos + src_n,
182 Shift (ppos - begidx));
183 std::for_each (vec.begin() + pos + src_n, vec.end(),
185 this->storeDataSpan();
186 return pflag && (vec.data() == orig);
190 //*****************************************************************************
194 * @brief Constructor. Makes a new vector.
195 * @param auxid The auxid of the variable this vector represents.
196 * @param size Initial size of the new vector.
197 * @param capacity Initial capacity of the new vector.
198 * @param linkedVec Ownership of the linked vector.
200 template <class HOLDER>
201 JaggedVecVectorT<HOLDER>::JaggedVecVectorT (auxid_t auxid,
204 std::unique_ptr<IAuxTypeVector> linkedVec)
205 : Base (auxid, &m_vec, linkedVec.get(), false),
206 m_linkedVecHolder (std::move (linkedVec))
208 m_vec.reserve (capacity);
214 * @brief Copy constructor.
216 template <class HOLDER>
217 JaggedVecVectorT<HOLDER>::JaggedVecVectorT (const JaggedVecVectorT& other)
218 : Base (other.auxid(), &m_vec, false, false),
220 m_linkedVecHolder (other.m_linkedVec->clone())
222 Base::m_linkedVec = m_linkedVecHolder.get();
227 * @brief Move constructor.
229 template <class HOLDER>
230 JaggedVecVectorT<HOLDER>::JaggedVecVectorT (JaggedVecVectorT&& other)
231 : Base (other.auxid(), &m_vec, false, other.m_linkedVec),
232 m_vec (std::move (other.m_vec)),
233 m_linkedVecHolder (std::move (other.m_linkedVecHolder))
239 * @brief Make a copy of this vector.
241 template <class HOLDER>
243 std::unique_ptr<IAuxTypeVector> JaggedVecVectorT<HOLDER>::clone() const
245 return std::make_unique<JaggedVecVectorT> (*this);
250 * @brief Return ownership of the linked vector.
252 template <class HOLDER>
254 std::unique_ptr<IAuxTypeVector> JaggedVecVectorT<HOLDER>::linkedVector()
256 return std::move (m_linkedVecHolder);