22#include "cc_tools_qt/details/ToolsFieldBase.h"
23#include "cc_tools_qt/field/ToolsArrayListField.h"
25#include "comms/field/ArrayList.h"
40template <
typename TField>
41class ToolsArrayListFieldImpl :
public ToolsFieldBase<cc_tools_qt::field::ToolsArrayListField, TField>
43 using Base = ToolsFieldBase<cc_tools_qt::field::ToolsArrayListField, TField>;
45 using ValueType =
typename Field::ValueType;
46 using ElementType =
typename ValueType::value_type;
49 using SerialisedSeq =
typename Base::SerialisedSeq;
50 using Ptr =
typename Base::Ptr;
51 using ActPtr =
typename Base::ActPtr;
52 using Members =
typename Base::Members;
54 using WrapFieldCallbackFunc = std::function<ToolsFieldPtr (ElementType&)>;
56 explicit ToolsArrayListFieldImpl(Field& fieldRef)
61 ToolsArrayListFieldImpl(
const ToolsArrayListFieldImpl&) =
default;
62 ToolsArrayListFieldImpl(ToolsArrayListFieldImpl&&) =
default;
63 virtual ~ToolsArrayListFieldImpl() noexcept = default;
65 ToolsArrayListFieldImpl& operator=(const ToolsArrayListFieldImpl&) = delete;
67 void setWrapFieldCallback(WrapFieldCallbackFunc&& func)
70 m_wrapFieldFunc = std::move(func);
74 virtual bool isHiddenSerializationImpl()
const override
76 static constexpr bool NoPrefix =
77 (!Field::hasElemFixedSerLengthFieldPrefix()) &&
78 (!Field::hasElemSerLengthFieldPrefix()) &&
79 (!Field::hasSerLengthFieldPrefix()) &&
80 (!Field::hasSizeFieldPrefix());
82 static constexpr bool NoSuffix =
83 (!Field::hasTerminationFieldSuffix()) &&
84 (!Field::hasTrailingFieldSuffix());
86 return NoPrefix && NoSuffix;
89 virtual void addFieldImpl()
override
93 Field::hasFixedValue(),
98 addFieldInternal(Tag());
101 virtual void removeFieldImpl(
int idx)
override
105 Field::hasFixedValue(),
110 removeFieldInternal(idx, Tag());
113 virtual bool setSerialisedValueImpl([[maybe_unused]]
const SerialisedSeq& value)
override
115 [[maybe_unused]]
static constexpr bool Must_not_be_called =
false;
116 assert(Must_not_be_called);
120 virtual unsigned sizeImpl()
const override
122 return static_cast<unsigned>(Base::field().value().size());
125 virtual bool hasFixedSizeImpl()
const override
127 return Field::hasFixedSize();
130 virtual void adjustFixedSizeImpl()
override
134 Field::hasFixedValue(),
137 Field::hasFixedSize(),
142 adjustFixedSizeInternal(Tag());
145 virtual Ptr cloneImpl()
override
147 ActPtr ptr(
new ToolsArrayListFieldImpl(Base::field()));
148 static_cast<ToolsArrayListFieldImpl<TField>*
>(ptr.get())->m_wrapFieldFunc = m_wrapFieldFunc;
152 virtual void refreshMembersImpl()
override
156 Field::hasFixedValue(),
161 refreshMembersInternal(Tag());
164 virtual void membersUpdatedImpl()
override
166 if (isHiddenSerializationImpl()) {
170 auto& mems = Base::getMembers();
171 for (
auto& m : mems) {
173 m->forceHiddenSerialization();
178 struct HasFixedSizeTag {};
179 struct HasVarSizeTag {};
180 struct HasFeatureTag {};
181 struct NoFeatureTag {};
183 void adjustFixedSizeInternal(HasVarSizeTag)
185 [[maybe_unused]]
static constexpr bool Must_not_be_called =
false;
186 assert(Must_not_be_called);
189 void adjustFixedSizeInternal(HasFixedSizeTag)
191 COMMS_GNU_WARNING_PUSH
192#if defined(NDEBUG) && COMMS_IS_GCC_13 && (COMMS_IS_CPP20)
193 COMMS_GNU_WARNING_DISABLE(
"-Wstringop-overflow")
196 Base::field().value().resize(Field::fixedSize());
197 COMMS_GNU_WARNING_POP
200 void adjustFixedSizeInternal(NoFeatureTag)
202 [[maybe_unused]]
static constexpr bool Must_not_be_called =
false;
203 assert(Must_not_be_called);
206 void addFieldInternal(HasFeatureTag)
208 auto& col = Base::field().value();
209 col.push_back(ElementType());
210 refreshMembersInternal(HasFeatureTag());
213 void addFieldInternal(NoFeatureTag)
215 [[maybe_unused]]
static constexpr bool Must_not_be_called =
false;
216 assert(Must_not_be_called);
219 void removeFieldInternal(
int idx, HasFeatureTag)
221 auto& storage = Base::field().value();
222 if (
static_cast<decltype(idx)
>(storage.size()) <= idx) {
226 storage.erase(storage.begin() + idx);
227 refreshMembersInternal(HasFeatureTag());
230 void removeFieldInternal([[maybe_unused]]
int idx, NoFeatureTag)
232 [[maybe_unused]]
static constexpr bool Must_not_be_called =
false;
233 assert(Must_not_be_called);
236 void refreshMembersInternal(HasFeatureTag)
238 if (!m_wrapFieldFunc) {
239 [[maybe_unused]]
static constexpr bool Callback_is_not_set =
false;
240 assert(Callback_is_not_set);
243 auto& storage = Base::field().value();
245 mems.reserve(storage.size());
246 for (
auto& f : storage) {
247 mems.push_back(m_wrapFieldFunc(f));
248 if (!mems.back()->canWrite()) {
249 mems.back()->reset();
250 assert(mems.back()->canWrite());
254 Base::setMembers(std::move(mems));
257 void refreshMembersInternal(NoFeatureTag)
261 WrapFieldCallbackFunc m_wrapFieldFunc;
264template <
typename TField>
265auto makeArrayListField(TField& field)
267 return std::make_unique<ToolsArrayListFieldImpl<TField>>(field);