ATLAS Offline Software
Loading...
Searching...
No Matches
TargetBuffer_t.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4#ifndef TargetBuffer_t_H
5#define TargetBuffer_t_H
6
7#include <vector>
8#ifndef NDEBUG
9# include <stdexcept>
10#endif
11
12namespace TTN {
13 class DoubleBuffer_t;
14
15 template <typename T_BaseType, typename T_BufferType=const T_BaseType, typename T_VectorType=const std::vector<T_BaseType> >
16
23 friend class DoubleBuffer_t;
24 template <typename T1, typename T2,typename T3> friend class BufferBase_t;
25
26 public:
27 BufferBase_t(T_VectorType &buffer)
28 : m_ptr (&(buffer[0]))
29#ifndef NDEBUG
30 // debug code
31 , m_maxIndex(buffer.size())
32 , m_bufferStart(buffer.data())
33 , m_bufferEnd(m_bufferStart + buffer.size())//assumed contiguous
34#endif
35 {
36 }
37
38 protected:
39
40 template <typename T1, typename T2,typename T3>
42 : m_ptr(buffer.m_ptr)
43#ifndef NDEBUG
44 , m_maxIndex(buffer.m_maxIndex)
46 , m_bufferEnd(buffer.m_bufferEnd)
47#endif
48 {
49 }
50
51 template <typename T1, typename T2,typename T3>
54 {
55 m_ptr=buffer.m_ptr;
56#ifndef NDEBUG
57 m_maxIndex=buffer.m_maxIndex;
58 m_bufferStart=buffer.m_bufferStart;
59 m_bufferEnd=buffer.m_bufferEnd;
60#endif
61 return *this;
62 }
63
64 // last two arguments are only needed for the optional range check.
65 BufferBase_t(T_BufferType *buffer,
66 typename std::vector<T_BaseType>::size_type max_idx [[maybe_unused]],
67 const std::vector<double> & full_vector [[maybe_unused]])
68 : m_ptr(buffer)
69#ifndef NDEBUG
70 // debug code
71 , m_maxIndex(max_idx)
72 , m_bufferStart(full_vector.data())
73 , m_bufferEnd(m_bufferStart+full_vector.size())//assumed contiguous
74#endif
75 {
76 }
77
78 public:
79 const T_BaseType &operator [](typename std::vector<T_BaseType>::size_type idx) const {
80 return m_ptr[optionalRangeCheck(idx)];
81 }
82
83 const T_BaseType &upper_bound_at(typename std::vector<T_BaseType>::size_type idx) const {
85 }
86
87 protected:
88 T_BufferType *m_ptr;
89#ifdef NDEBUG
90 typename std::vector<T_BaseType>::size_type optionalRangeCheck(typename std::vector<T_BaseType>::size_type idx) const {
91 return idx;
92 }
93 typename std::vector<T_BaseType>::size_type optionalRangeCheckUpperBound(typename std::vector<T_BaseType>::size_type idx) const {
94 return idx;
95 }
96#else
97 // debug code
98 typename std::vector<T_BaseType>::size_type optionalRangeCheck(typename std::vector<T_BaseType>::size_type idx) const {
99 if (idx>=m_maxIndex || &(m_ptr[idx])<m_bufferStart || &(m_ptr[idx])>=m_bufferEnd) {
100 throwRangeError(idx);
101 }
102 return idx;
103 }
104 typename std::vector<T_BaseType>::size_type optionalRangeCheckUpperBound(typename std::vector<T_BaseType>::size_type idx) const {
105 // allow for idx==0
106 if (idx>0 && (idx-1>=m_maxIndex || &(m_ptr[idx-1])<m_bufferStart || &(m_ptr[idx-1])>=m_bufferEnd)) {
107 throwRangeError(idx);
108 }
109 return idx;
110 }
111 void throwRangeError(typename std::vector<T_BaseType>::size_type idx) const;
112
113 typename std::vector<T_BaseType>::size_type m_maxIndex;
114 const T_BaseType *m_bufferStart;
115 const T_BaseType *m_bufferEnd;
116#endif
117 };
118
124 class Buffer_t : public BufferBase_t<double,double,std::vector<double> >
125 {
126 public:
127 Buffer_t(std::vector<double> &buffer) : BufferBase_t<double,double, std::vector<double> >(buffer) {}
128 Buffer_t(double *buffer, typename std::vector<double>::size_type max_idx, const std::vector<double> & full_vector)
129 : BufferBase_t<double,double,std::vector<double> >(buffer,max_idx,full_vector)
130 {}
131
132 double &operator [](typename std::vector<double>::size_type idx) {
133 return m_ptr[optionalRangeCheck(idx)];
134 }
135
136 double &upper_bound_at(typename std::vector<double>::size_type idx) {
138 }
139 };
140
145 class ConstBuffer_t : public BufferBase_t<double,const double, const std::vector<double> >
146 {
147 public:
148 ConstBuffer_t(const Buffer_t &buffer) : BufferBase_t<double,const double, const std::vector<double> >(buffer) {}
149 ConstBuffer_t(const std::vector<double> &buffer) : BufferBase_t<double,const double, const std::vector<double> >(buffer) {}
151 operator=(const Buffer_t &buffer) { BufferBase_t<double,const double, const std::vector<double> >::operator=(buffer); return *this;}
152 };
153
154
164 {
165 public:
166 void clear(unsigned int max_buffer) {
167 resize(max_buffer);
168 std::fill(m_buffer.begin(),m_buffer.end(),double{});
169 }
170
171 Buffer_t operator[](unsigned int fold_idx) {
172 std::vector<double>::size_type max_idx=m_buffer.size()/2;
173 return Buffer_t(&(m_buffer[(fold_idx%2) * max_idx ]), max_idx,m_buffer);
174 }
175
181 std::vector<double> releaseData(std::vector<double>::size_type final_size, unsigned int fold_idx) {
182 if (fold_idx%2 !=0 ) {
183 std::vector<double>::size_type max_idx=m_buffer.size()/2;
184 std::vector<double>::const_iterator first_iter(m_buffer.begin()+max_idx);
185 std::vector<double>::const_iterator last_iter(first_iter+max_idx);
186 std::copy(first_iter,last_iter, m_buffer.begin());
187 }
188 m_buffer.resize(final_size);
189 return std::move(m_buffer);
190 }
191
192 private:
193 void resize(unsigned int max_buffer) {
194 max_buffer*=2;
195 if (max_buffer>m_buffer.size()) {
196 m_buffer.resize(max_buffer,double{});
197 }
198 }
199
200 std::vector<double> m_buffer;
201 };
202
203}
204#endif
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
Helper class which adds a range check to an array access if NDEBUG is not defined.
void throwRangeError(typename std::vector< T_BaseType >::size_type idx) const
BufferBase_t(T_BufferType *buffer, typename std::vector< T_BaseType >::size_type max_idx, const std::vector< double > &full_vector)
std::vector< T_BaseType >::size_type optionalRangeCheck(typename std::vector< T_BaseType >::size_type idx) const
std::vector< T_BaseType >::size_type optionalRangeCheckUpperBound(typename std::vector< T_BaseType >::size_type idx) const
std::vector< T_BaseType >::size_type m_maxIndex
friend class DoubleBuffer_t
friend class BufferBase_t
const T_BaseType & operator[](typename std::vector< T_BaseType >::size_type idx) const
BufferBase_t(T_VectorType &buffer)
const T_BaseType * m_bufferStart
const T_BaseType * m_bufferEnd
const T_BaseType & upper_bound_at(typename std::vector< T_BaseType >::size_type idx) const
BufferBase_t(const BufferBase_t< T1, T2, T3 > &buffer)
T_BufferType * m_ptr
BufferBase_t & operator=(const BufferBase_t< T1, T2, T3 > &buffer)
Reference to one of the halves provided by the DoubleBuffer_t.
double & operator[](typename std::vector< double >::size_type idx)
double & upper_bound_at(typename std::vector< double >::size_type idx)
Buffer_t(std::vector< double > &buffer)
Buffer_t(double *buffer, typename std::vector< double >::size_type max_idx, const std::vector< double > &full_vector)
Read only reference to one of the halves provided by the DoubleBuffer_t.
ConstBuffer_t(const std::vector< double > &buffer)
ConstBuffer_t(const Buffer_t &buffer)
ConstBuffer_t & operator=(const Buffer_t &buffer)
The temporary buffer for internal computations which is split into two halves.
void resize(unsigned int max_buffer)
std::vector< double > releaseData(std::vector< double >::size_type final_size, unsigned int fold_idx)
move the final result to its destination
std::vector< double > m_buffer
void clear(unsigned int max_buffer)
Buffer_t operator[](unsigned int fold_idx)
STL namespace.