31#include "comms/comms.h"
33#include "FieldWrapper.h"
38namespace field_wrapper
41class CC_API ArrayListWrapper :
public FieldWrapper
45 typedef std::vector<FieldWrapperPtr> Members;
46 typedef std::unique_ptr<ArrayListWrapper> Ptr;
49 ArrayListWrapper(
const ArrayListWrapper&) =
delete;
50 ArrayListWrapper& operator=(
const ArrayListWrapper&) =
delete;
52 virtual ~ArrayListWrapper() noexcept;
56 void removeField(
int idx);
58 unsigned size() const;
60 bool hasFixedSize() const;
62 void adjustFixedSize();
64 Members& getMembers();
66 const Members& getMembers() const;
68 void setMembers(Members&& members);
72 void refreshMembers();
74 using PrefixFieldInfo = std::pair<
int, SerialisedSeq>;
76 PrefixFieldInfo getPrefixFieldInfo() const;
79 virtual
void addFieldImpl() = 0;
80 virtual
void removeFieldImpl(
int idx) = 0;
81 virtual
unsigned sizeImpl() const = 0;
82 virtual
bool hasFixedSizeImpl() const = 0;
83 virtual
void adjustFixedSizeImpl() = 0;
84 virtual Ptr cloneImpl() = 0;
85 virtual
void refreshMembersImpl() = 0;
86 virtual PrefixFieldInfo getPrefixFieldInfoImpl() const = 0;
88 void dispatchImpl(FieldWrapperHandler& handler);
94template <typename TField>
95class ArrayListWrapperT : public FieldWrapperT<ArrayListWrapper, TField>
97 using Base = FieldWrapperT<ArrayListWrapper, TField>;
99 using ValueType =
typename Field::ValueType;
100 using ElementType =
typename ValueType::value_type;
103 using SerialisedSeq =
typename Base::SerialisedSeq;
104 using Ptr =
typename Base::Ptr;
105 using PrefixFieldInfo =
typename Base::PrefixFieldInfo;
107 typedef std::function<FieldWrapperPtr (ElementType&)> WrapFieldCallbackFunc;
109 explicit ArrayListWrapperT(Field& fieldRef)
114 ArrayListWrapperT(
const ArrayListWrapperT&) =
default;
115 ArrayListWrapperT(ArrayListWrapperT&&) =
default;
116 virtual ~ArrayListWrapperT() noexcept = default;
118 ArrayListWrapperT& operator=(const ArrayListWrapperT&) = delete;
120 void setWrapFieldCallback(WrapFieldCallbackFunc&& func)
123 m_wrapFieldFunc = std::move(func);
128 virtual void addFieldImpl()
override
130 auto& col = Base::field().value();
132 auto& mems = Base::getMembers();
134 decltype(&col[0]) firstElemPtr =
nullptr;
136 firstElemPtr = &col[0];
139 col.push_back(ElementType());
140 if (!m_wrapFieldFunc) {
141 [[maybe_unused]]
static constexpr bool Callback_is_not_set =
false;
142 assert(Callback_is_not_set);
147 if (firstElemPtr == &col[0]) {
148 mems.push_back(m_wrapFieldFunc(col.back()));
149 assert(col.size() == mems.size());
154 mems.reserve(col.size());
155 for (
auto& f : col) {
156 mems.push_back(m_wrapFieldFunc(f));
159 assert(col.size() == mems.size());
162 virtual void removeFieldImpl(
int idx)
override
164 auto& storage = Base::field().value();
165 if (
static_cast<decltype(idx)
>(storage.size()) <= idx) {
169 storage.erase(storage.begin() + idx);
170 auto& mems = Base::getMembers();
172 mems.reserve(storage.size());
173 for (
auto& f : storage) {
174 mems.push_back(m_wrapFieldFunc(f));
178 virtual bool setSerialisedValueImpl([[maybe_unused]]
const SerialisedSeq& value)
override
180 [[maybe_unused]]
static constexpr bool Must_not_be_called =
false;
181 assert(Must_not_be_called);
185 virtual unsigned sizeImpl()
const override
187 return static_cast<unsigned>(Base::field().value().size());
190 virtual bool hasFixedSizeImpl()
const override
192 return Field::hasFixedSize();
195 virtual void adjustFixedSizeImpl()
override
198 typename std::conditional<
199 Field::hasFixedSize(),
203 adjustFixedSizeInternal(Tag());
206 virtual Ptr cloneImpl()
override
208 Ptr ptr(
new ArrayListWrapperT(Base::field()));
209 static_cast<ArrayListWrapperT<TField>*
>(ptr.get())->m_wrapFieldFunc = m_wrapFieldFunc;
213 virtual void refreshMembersImpl()
override
215 if (!m_wrapFieldFunc) {
216 [[maybe_unused]]
static constexpr bool Callback_is_not_set =
false;
217 assert(Callback_is_not_set);
220 auto& storage = Base::field().value();
221 auto& mems = Base::getMembers();
223 mems.reserve(storage.size());
224 for (
auto& f : storage) {
225 mems.push_back(m_wrapFieldFunc(f));
226 if (!mems.back()->canWrite()) {
227 mems.back()->reset();
228 assert(mems.back()->canWrite());
233 virtual PrefixFieldInfo getPrefixFieldInfoImpl()
const override
236 typename std::conditional<
237 Field::hasSizeFieldPrefix(),
239 typename std::conditional<
240 Field::hasSerLengthFieldPrefix(),
246 return getPrefixFieldInfoInternal(Tag());
250 struct NoPrefixFieldTag {};
251 struct ElemCountFieldTag {};
252 struct SerLengthFieldTag {};
253 struct SerLengthFieldFixedTag {};
254 struct SerLengthFieldVarTag {};
255 struct HasFixedSizeTag {};
256 struct HasVarSizeTag {};
258 PrefixFieldInfo getPrefixFieldInfoInternal(NoPrefixFieldTag)
const
260 return std::make_pair(0, SerialisedSeq());
263 PrefixFieldInfo getPrefixFieldInfoInternal(ElemCountFieldTag)
const
265 using SizeField =
typename Field::SizeFieldPrefix;
267 sizeField.setValue(Base::field().value().size());
268 return std::make_pair(
static_cast<int>(sizeField.getValue()), getPrefixFieldSerialised(sizeField));
271 PrefixFieldInfo getPrefixFieldInfoInternal(SerLengthFieldTag)
const
273 using LengthField =
typename Field::SerLengthFieldPrefix;
275 typename std::conditional<
276 LengthField::hasVarLength(),
277 SerLengthFieldVarTag,
278 SerLengthFieldFixedTag
281 return getPrefixFieldInfoInternal(Tag());
284 PrefixFieldInfo getPrefixFieldInfoInternal(SerLengthFieldFixedTag)
const
286 using LengthField =
typename Field::SerLengthFieldPrefix;
287 LengthField lenField;
288 lenField.setValue(Base::field().length() - LengthField::maxLength());
289 return std::make_pair(
static_cast<int>(lenField.getValue()), getPrefixFieldSerialised(lenField));
292 PrefixFieldInfo getPrefixFieldInfoInternal(SerLengthFieldVarTag)
const
294 using LengthField =
typename Field::SerLengthFieldPrefix;
296 auto fullLen = Base::field().length();
297 LengthField lenFieldTmp;
298 lenFieldTmp.setValue(fullLen);
299 auto tmpLen = lenFieldTmp.length();
300 LengthField lenField;
301 lenField.setValue(fullLen - tmpLen);
302 if (lenField.length() == tmpLen) {
303 assert(
static_cast<int>(lenField.getValue()) <= std::numeric_limits<int>::max());
304 return std::make_pair(
static_cast<int>(lenField.getValue()), getPrefixFieldSerialised(lenField));
307 lenField.setValue(fullLen - lenField.length());
308 assert(
static_cast<int>(lenField.getValue()) <= std::numeric_limits<int>::max());
309 return std::make_pair(
static_cast<int>(lenField.getValue()), getPrefixFieldSerialised(lenField));
312 template <
typename TPrefixField>
313 SerialisedSeq getPrefixFieldSerialised(
const TPrefixField& prefixField)
const
315 SerialisedSeq serData;
316 serData.reserve(prefixField.length());
317 auto writeIter = std::back_inserter(serData);
318 [[maybe_unused]]
auto es = prefixField.write(writeIter, serData.max_size());
319 assert(es == comms::ErrorStatus::Success);
323 void adjustFixedSizeInternal(HasVarSizeTag)
325 [[maybe_unused]]
static constexpr bool Must_not_be_called =
false;
326 assert(Must_not_be_called);
329 void adjustFixedSizeInternal(HasFixedSizeTag)
331 COMMS_GNU_WARNING_PUSH
332#if defined(NDEBUG) && COMMS_IS_GCC_13 && (COMMS_IS_CPP20)
333 COMMS_GNU_WARNING_DISABLE(
"-Wstringop-overflow")
336 Base::field().value().resize(Field::fixedSize());
337 COMMS_GNU_WARNING_POP
341 WrapFieldCallbackFunc m_wrapFieldFunc;
344using ArrayListWrapperPtr = ArrayListWrapper::Ptr;
346template <
typename TField>
348makeArrayListWrapper(TField& field)
352 new ArrayListWrapperT<TField>(field));
355template <
typename TField>
356std::unique_ptr<ArrayListWrapperT<TField> >
357makeDowncastedArrayListWrapper(TField& field)
360 std::unique_ptr<ArrayListWrapperT<TField> >(
361 new ArrayListWrapperT<TField>(field));