21#include "cc_tools_qt/details/ToolsFieldBase.h"
22#include "cc_tools_qt/field/ToolsArrayListField.h"
24#include "comms/field/ArrayList.h"
39template <
typename TField>
40class ToolsArrayListFieldImpl :
public ToolsFieldBase<cc_tools_qt::field::ToolsArrayListField, TField>
42 using Base = ToolsFieldBase<cc_tools_qt::field::ToolsArrayListField, TField>;
44 using ValueType =
typename Field::ValueType;
45 using ElementType =
typename ValueType::value_type;
48 using SerialisedSeq =
typename Base::SerialisedSeq;
49 using Ptr =
typename Base::Ptr;
50 using ActPtr =
typename Base::ActPtr;
51 using Members =
typename Base::Members;
53 using WrapFieldCallbackFunc = std::function<ToolsFieldPtr (ElementType&)>;
55 explicit ToolsArrayListFieldImpl(Field& fieldRef)
60 ToolsArrayListFieldImpl(
const ToolsArrayListFieldImpl&) =
default;
61 ToolsArrayListFieldImpl(ToolsArrayListFieldImpl&&) =
default;
62 virtual ~ToolsArrayListFieldImpl() noexcept = default;
64 ToolsArrayListFieldImpl& operator=(const ToolsArrayListFieldImpl&) = delete;
66 void setWrapFieldCallback(WrapFieldCallbackFunc&& func)
69 m_wrapFieldFunc = std::move(func);
73 virtual bool isHiddenSerializationImpl()
const override
75 static constexpr bool NoPrefix =
76 (!Field::hasElemFixedSerLengthFieldPrefix()) &&
77 (!Field::hasElemSerLengthFieldPrefix()) &&
78 (!Field::hasSerLengthFieldPrefix()) &&
79 (!Field::hasSizeFieldPrefix());
81 static constexpr bool NoSuffix =
82 (!Field::hasTerminationFieldSuffix()) &&
83 (!Field::hasTrailingFieldSuffix());
85 return NoPrefix && NoSuffix;
88 virtual void addFieldImpl()
override
92 Field::hasFixedValue(),
97 addFieldInternal(Tag());
100 virtual void removeFieldImpl(
int idx)
override
104 Field::hasFixedValue(),
109 removeFieldInternal(idx, Tag());
112 virtual bool setSerialisedValueImpl([[maybe_unused]]
const SerialisedSeq& value)
override
114 [[maybe_unused]]
static constexpr bool Must_not_be_called =
false;
115 assert(Must_not_be_called);
119 virtual unsigned sizeImpl()
const override
121 return static_cast<unsigned>(Base::field().value().size());
124 virtual bool hasFixedSizeImpl()
const override
126 return Field::hasFixedSize();
129 virtual void adjustFixedSizeImpl()
override
133 Field::hasFixedValue(),
136 Field::hasFixedSize(),
141 adjustFixedSizeInternal(Tag());
144 virtual Ptr cloneImpl()
override
146 ActPtr ptr(
new ToolsArrayListFieldImpl(Base::field()));
147 static_cast<ToolsArrayListFieldImpl<TField>*
>(ptr.get())->m_wrapFieldFunc = m_wrapFieldFunc;
151 virtual void refreshMembersImpl()
override
155 Field::hasFixedValue(),
160 refreshMembersInternal(Tag());
163 virtual void membersUpdatedImpl()
override
165 if (isHiddenSerializationImpl()) {
169 auto& mems = Base::getMembers();
170 for (
auto& m : mems) {
172 m->forceHiddenSerialization();
177 struct HasFixedSizeTag {};
178 struct HasVarSizeTag {};
179 struct HasFeatureTag {};
180 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;
265template <
typename TField>
266auto makeArrayListField(TField& field)
268 return std::make_unique<ToolsArrayListFieldImpl<TField>>(field);