1 #ifndef PandaTree_Framework_Array_h 2 #define PandaTree_Framework_Array_h 20 class Array :
public E::base_type::array_type {
23 typedef typename E::base_type::array_type base_type;
25 typedef value_type& reference;
26 typedef value_type
const& const_reference;
27 typedef value_type* pointer;
28 typedef value_type
const* const_pointer;
32 Array(UInt_t size,
char const* name =
"") : base_type(name,
sizeof(E), kFALSE) { allocate_(size); }
33 Array(self_type
const& src) : base_type(src.name_,
sizeof(E), kFALSE) { allocate_(src.data.nmax());
copy(src); }
35 self_type& operator=(self_type
const& rhs) {
copy(rhs);
return *
this; }
38 reference
at(UInt_t idx);
40 const_reference
at(UInt_t idx)
const;
44 const_reference
operator[](UInt_t idx)
const {
return *const_addr_(idx); }
46 iterator
begin() {
return iterator(addr_(), ContainerBase::unitSize_); }
48 const_iterator
begin()
const {
return const_iterator(const_addr_(), ContainerBase::unitSize_); }
50 iterator
end() {
return iterator(addr_(data.nmax()), ArrayBase::ContainerBase::unitSize_); }
52 const_iterator
end()
const {
return const_iterator(const_addr_(data.nmax()), ContainerBase::unitSize_); }
54 reference
front() {
return *addr_(); }
56 const_reference
front()
const {
return *const_addr_(); }
58 reference
back() {
return *addr_(data.nmax() - 1); }
60 const_reference
back()
const {
return *const_addr_(data.nmax() - 1); }
62 void copy(self_type
const&);
66 Element& elemAt(UInt_t idx)
override {
return at(idx); }
67 Element const& elemAt(UInt_t idx)
const override {
return at(idx); }
69 std::vector<UInt_t> sort(ContainerBase::Comparison
const&)
override;
71 void print(std::ostream& = std::cout, UInt_t level = 1)
const override;
72 void dump(std::ostream& = std::cout)
const override;
74 typename value_type::datastore data{};
77 Array(
char const* name, UInt_t unitSize, Bool_t dummy) : base_type(name, unitSize, kFALSE) {}
80 value_type* addr_(UInt_t idx = 0);
81 value_type
const* const_addr_(UInt_t idx = 0)
const;
84 typename std::enable_if<std::is_constructible<T>::value>::type allocate_(UInt_t);
86 typename std::enable_if<!std::is_constructible<T>::value>::type allocate_(UInt_t);
92 if (ContainerBase::array_) {
95 for (UInt_t iP(0); iP != data.nmax(); ++iP, ++p)
98 std::allocator<value_type>().deallocate(addr_(), data.nmax());
102 ContainerBase::array_ = 0;
107 typename Array<E>::reference
110 if (_idx >= data.nmax())
111 throw std::out_of_range((ContainerBase::name_ +
"::at").Data());
117 typename Array<E>::const_reference
120 if (_idx >= data.nmax())
121 throw std::out_of_range((ContainerBase::name_ +
"::at").Data());
123 return *const_addr_(_idx);
130 if (_src.ContainerBase::unitSize_ != ContainerBase::unitSize_)
131 throw std::runtime_error((ContainerBase::name_ +
"::copy incompatible array").Data());
133 if (_src.data.nmax() != data.nmax())
134 throw std::runtime_error((ContainerBase::name_ +
"::copy array size does not match").Data());
136 for (UInt_t iP(0); iP != data.nmax(); ++iP)
137 (*
this)[iP] = _src[iP];
147 auto indexComp([
this, &_c](UInt_t i1, UInt_t i2)->Bool_t {
148 return _c((*
this)[i1], (*
this)[i2]);
151 std::vector<UInt_t> sortedIndices(data.nmax());
152 for (UInt_t iP(0); iP != data.nmax(); ++iP)
153 sortedIndices[iP] = iP;
155 std::sort(sortedIndices.begin(), sortedIndices.end(), indexComp);
158 for (UInt_t iP(0); iP != data.nmax(); ++iP)
159 (*
this)[iP] = tmpCollection[sortedIndices[iP]];
161 return sortedIndices;
168 _out << E::typeName() <<
"Array(" << ArrayBase::size() <<
")" << std::endl;
176 _out << E::typeName() <<
"Array(" << ArrayBase::size() <<
")" << std::endl;
182 typename Array<E>::value_type*
188 return reinterpret_cast<value_type*
>(ContainerBase::array_ + _idx * ContainerBase::unitSize_);
193 typename Array<E>::value_type
const*
199 return reinterpret_cast<value_type const*
>(ContainerBase::array_ + _idx * ContainerBase::unitSize_);
205 typename std::enable_if<std::is_constructible<T>::value>::type
208 data.allocate(_nmax);
210 ContainerBase::array_ =
reinterpret_cast<Char_t*
>(std::allocator<value_type>().allocate(data.nmax()));
212 value_type* p(addr_());
213 for (UInt_t iP(0); iP != data.nmax(); ++iP, ++p)
214 new (p) value_type(data, iP);
220 typename std::enable_if<!std::is_constructible<T>::value>::type
223 throw std::runtime_error((
"Cannot create an Array of pure-virtual elements (" + ContainerBase::name_ +
")").Data());
const_reference back() const
Reference to the last element.
Definition: Array.h:60
void dump(std::ostream &=std::cout) const override
Dump the object content.
Definition: ContainerBase.cc:23
void print(std::ostream &=std::cout, UInt_t level=1) const override
Print the object content.
Definition: ContainerBase.cc:7
const_reference front() const
Reference to the first element.
Definition: Array.h:56
const_iterator begin() const
Return an iterator pointing to the first element.
Definition: Array.h:48
iterator end()
Return an iterator pointing to the end of the array (invalid address)
Definition: Array.h:50
Template class for fixed-size container implementations. Inherits from base_type::array_type of the e...
Definition: Array.h:20
void copy(self_type const &)
Copy the array contents.
Definition: Array.h:128
void setName(char const *name) final
Set object name.
Definition: ContainerBase.h:26
reference operator[](UInt_t idx)
Element accessor with no range check.
Definition: Array.h:42
const_iterator end() const
Return an iterator pointing to the end of the array (invalid address)
Definition: Array.h:52
const_reference operator[](UInt_t idx) const
Element accessor with no range check.
Definition: Array.h:44
reference back()
Reference to the last element.
Definition: Array.h:58
Base class for elements of containers.
Definition: Element.h:32
reference front()
Reference to the first element.
Definition: Array.h:54
Iterator class for containers.
Definition: Iterator.h:11
reference at(UInt_t idx)
Element accessor with range check.
Definition: Array.h:108
iterator begin()
Return an iterator pointing to the first element.
Definition: Array.h:46