20#include "cc_tools_qt/details/ToolsFieldBase.h"
21#include "cc_tools_qt/field/ToolsArrayListField.h"
23#include "comms/field/ArrayList.h"
38template <
typename TField>
39class ToolsArrayListFieldImpl :
public ToolsFieldBase<cc_tools_qt::field::ToolsArrayListField, TField>
41 using Base = ToolsFieldBase<cc_tools_qt::field::ToolsArrayListField, TField>;
43 using ValueType =
typename Field::ValueType;
44 using ElementType =
typename ValueType::value_type;
47 using SerialisedSeq =
typename Base::SerialisedSeq;
48 using Ptr =
typename Base::Ptr;
49 using ActPtr =
typename Base::ActPtr;
50 using Members =
typename Base::Members;
52 using WrapFieldCallbackFunc = std::function<ToolsFieldPtr (ElementType&)>;
54 explicit ToolsArrayListFieldImpl(Field& fieldRef)
59 ToolsArrayListFieldImpl(
const ToolsArrayListFieldImpl&) =
default;
60 ToolsArrayListFieldImpl(ToolsArrayListFieldImpl&&) =
default;
61 virtual ~ToolsArrayListFieldImpl() noexcept = default;
63 ToolsArrayListFieldImpl& operator=(const ToolsArrayListFieldImpl&) = delete;
65 void setWrapFieldCallback(WrapFieldCallbackFunc&& func)
68 m_wrapFieldFunc = std::move(func);
72 virtual bool isHiddenSerializationImpl()
const override
74 static constexpr bool NoPrefix =
75 (!Field::hasElemFixedSerLengthFieldPrefix()) &&
76 (!Field::hasElemSerLengthFieldPrefix()) &&
77 (!Field::hasSerLengthFieldPrefix()) &&
78 (!Field::hasSizeFieldPrefix());
80 static constexpr bool NoSuffix =
81 (!Field::hasTerminationFieldSuffix()) &&
82 (!Field::hasTrailingFieldSuffix());
84 return NoPrefix && NoSuffix;
87 virtual void addFieldImpl()
override
91 Field::hasFixedValue(),
96 addFieldInternal(Tag());
99 virtual void removeFieldImpl(
int idx)
override
103 Field::hasFixedValue(),
108 removeFieldInternal(idx, Tag());
111 virtual bool setSerialisedValueImpl([[maybe_unused]]
const SerialisedSeq& value)
override
113 [[maybe_unused]]
static constexpr bool Must_not_be_called =
false;
114 assert(Must_not_be_called);
118 virtual unsigned sizeImpl()
const override
120 return static_cast<unsigned>(Base::field().value().size());
123 virtual bool hasFixedSizeImpl()
const override
125 return Field::hasFixedSize();
128 virtual void adjustFixedSizeImpl()
override
132 Field::hasFixedValue(),
135 Field::hasFixedSize(),
140 adjustFixedSizeInternal(Tag());
143 virtual Ptr cloneImpl()
override
145 ActPtr ptr(
new ToolsArrayListFieldImpl(Base::field()));
146 static_cast<ToolsArrayListFieldImpl<TField>*
>(ptr.get())->m_wrapFieldFunc = m_wrapFieldFunc;
150 virtual void refreshMembersImpl()
override
154 Field::hasFixedValue(),
159 refreshMembersInternal(Tag());
162 virtual void membersUpdatedImpl()
override
164 if (isHiddenSerializationImpl()) {
168 auto& mems = Base::getMembers();
169 for (
auto& m : mems) {
171 m->forceHiddenSerialization();
176 struct HasFixedSizeTag {};
177 struct HasVarSizeTag {};
178 struct HasFeatureTag {};
179 struct NoFeatureTag {};
181 void adjustFixedSizeInternal(HasVarSizeTag)
183 [[maybe_unused]]
static constexpr bool Must_not_be_called =
false;
184 assert(Must_not_be_called);
187 void adjustFixedSizeInternal(HasFixedSizeTag)
189 COMMS_GNU_WARNING_PUSH
190#if defined(NDEBUG) && COMMS_IS_GCC_13 && (COMMS_IS_CPP20)
191 COMMS_GNU_WARNING_DISABLE(
"-Wstringop-overflow")
194 Base::field().value().resize(Field::fixedSize());
195 COMMS_GNU_WARNING_POP
198 void adjustFixedSizeInternal(NoFeatureTag)
200 [[maybe_unused]]
static constexpr bool Must_not_be_called =
false;
201 assert(Must_not_be_called);
204 void addFieldInternal(HasFeatureTag)
206 auto& col = Base::field().value();
207 col.push_back(ElementType());
208 refreshMembersInternal(HasFeatureTag());
211 void addFieldInternal(NoFeatureTag)
213 [[maybe_unused]]
static constexpr bool Must_not_be_called =
false;
214 assert(Must_not_be_called);
217 void removeFieldInternal(
int idx, HasFeatureTag)
219 auto& storage = Base::field().value();
220 if (
static_cast<decltype(idx)
>(storage.size()) <= idx) {
224 storage.erase(storage.begin() + idx);
225 refreshMembersInternal(HasFeatureTag());
228 void removeFieldInternal([[maybe_unused]]
int idx, NoFeatureTag)
230 [[maybe_unused]]
static constexpr bool Must_not_be_called =
false;
231 assert(Must_not_be_called);
234 void refreshMembersInternal(HasFeatureTag)
236 if (!m_wrapFieldFunc) {
237 [[maybe_unused]]
static constexpr bool Callback_is_not_set =
false;
238 assert(Callback_is_not_set);
241 auto& storage = Base::field().value();
243 mems.reserve(storage.size());
244 for (
auto& f : storage) {
245 mems.push_back(m_wrapFieldFunc(f));
246 if (!mems.back()->canWrite()) {
247 mems.back()->reset();
248 assert(mems.back()->canWrite());
252 Base::setMembers(std::move(mems));
255 void refreshMembersInternal(NoFeatureTag)
259 WrapFieldCallbackFunc m_wrapFieldFunc;
262template <
typename TField>
263auto makeArrayListField(TField& field)
265 return std::make_unique<ToolsArrayListFieldImpl<TField>>(field);