File indexing completed on 2025-01-18 09:54:47
0001
0002
0003
0004
0005
0006
0007
0008 #pragma once
0009
0010 #include <initializer_list>
0011 #include <limits>
0012
0013 #include "corecel/Config.hh"
0014
0015 #include "Collection.hh"
0016
0017 #include "detail/FillInvalid.hh"
0018
0019 namespace celeritas
0020 {
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045 template<class T, MemSpace M = MemSpace::host, class I = ItemId<T>>
0046 class CollectionBuilder
0047 {
0048 public:
0049
0050
0051 using CollectionT = Collection<T, Ownership::value, M, I>;
0052 using value_type = T;
0053 using size_type = typename CollectionT::size_type;
0054 using ItemIdT = typename CollectionT::ItemIdT;
0055 using ItemRangeT = typename CollectionT::ItemRangeT;
0056
0057
0058 public:
0059
0060 explicit CollectionBuilder(CollectionT* collection) : col_(*collection)
0061 {
0062 CELER_EXPECT(collection);
0063 }
0064
0065
0066 inline void resize(std::size_t count);
0067
0068
0069 inline void reserve(std::size_t count);
0070
0071
0072 template<class InputIterator>
0073 inline ItemRangeT insert_back(InputIterator first, InputIterator last);
0074
0075
0076 inline ItemRangeT insert_back(std::initializer_list<value_type> init);
0077
0078
0079 inline ItemIdT push_back(value_type const& element);
0080
0081
0082 size_type size() const { return col_.size(); }
0083
0084
0085 ItemIdT size_id() const { return ItemIdT{size()}; }
0086
0087 private:
0088
0089
0090 using StorageT = typename CollectionT::StorageT;
0091 StorageT& storage() { return col_.storage(); }
0092 StorageT const& storage() const { return col_.storage(); }
0093
0094
0095
0096 static constexpr std::size_t max_size()
0097 {
0098 return std::numeric_limits<size_type>::max();
0099 }
0100
0101 CollectionT& col_;
0102 };
0103
0104
0105
0106
0107
0108 template<class T, MemSpace M, class I>
0109 CollectionBuilder(Collection<T, Ownership::value, M, I>*)
0110 -> CollectionBuilder<T, M, I>;
0111
0112
0113
0114
0115
0116
0117
0118 template<class T, MemSpace M, class I>
0119 void CollectionBuilder<T, M, I>::reserve(std::size_t count)
0120 {
0121 CELER_EXPECT(count <= max_size());
0122 static_assert(M == MemSpace::host,
0123 "Reserve currently works only for host memory");
0124 this->storage().reserve(count);
0125 }
0126
0127
0128
0129
0130
0131 template<class T, MemSpace M, class I>
0132 template<class InputIterator>
0133 auto CollectionBuilder<T, M, I>::insert_back(InputIterator first,
0134 InputIterator last) -> ItemRangeT
0135 {
0136 CELER_EXPECT(std::distance(first, last) + this->storage().size()
0137 <= this->max_size());
0138 static_assert(M == MemSpace::host,
0139 "Insertion currently works only for host memory");
0140 auto start = this->size_id();
0141 this->storage().insert(this->storage().end(), first, last);
0142 return {start, this->size_id()};
0143 }
0144
0145
0146
0147
0148
0149 template<class T, MemSpace M, class I>
0150 auto CollectionBuilder<T, M, I>::insert_back(std::initializer_list<T> init)
0151 -> ItemRangeT
0152 {
0153 return this->insert_back(init.begin(), init.end());
0154 }
0155
0156
0157
0158
0159
0160 template<class T, MemSpace M, class I>
0161 auto CollectionBuilder<T, M, I>::push_back(T const& el) -> ItemIdT
0162 {
0163 CELER_EXPECT(this->storage().size() + 1 <= this->max_size());
0164 static_assert(M == MemSpace::host,
0165 "Insertion currently works only for host memory");
0166 auto result = this->size_id();
0167 this->storage().push_back(el);
0168 return result;
0169 }
0170
0171
0172
0173
0174
0175 template<class T, MemSpace M, class I>
0176 void CollectionBuilder<T, M, I>::resize(std::size_t count)
0177 {
0178 CELER_EXPECT(this->storage().empty());
0179 CELER_EXPECT(count <= max_size());
0180 this->storage() = StorageT(count);
0181 if constexpr (CELERITAS_DEBUG && M == MemSpace::host)
0182 {
0183
0184 detail::fill_invalid(&col_);
0185 }
0186 }
0187
0188
0189
0190
0191
0192
0193
0194 template<class T, MemSpace M, class I>
0195 CollectionBuilder<T, M, I>
0196 make_builder(Collection<T, Ownership::value, M, I>* collection)
0197 {
0198 CELER_EXPECT(collection);
0199 return CollectionBuilder<T, M, I>(collection);
0200 }
0201
0202
0203
0204
0205
0206
0207
0208 template<class T, MemSpace M, class I>
0209 void resize(Collection<T, Ownership::value, M, I>* collection, std::size_t size)
0210 {
0211 CELER_EXPECT(collection);
0212 CollectionBuilder<T, M, I>(collection).resize(size);
0213 }
0214
0215
0216 }