25#include <boost/algorithm/string.hpp>
36 template <
typename T,
typename CellType, u
int32_t Columns,
bool CellsCached>
39 template <
typename T,
typename CellType, u
int32_t Columns>
54 template <
typename T,
typename CellType, u
int32_t Columns>
69 template <
typename T,
typename CellType>
76 typedef std::vector<cell_type, typename std::allocator_traits<allocator_type>::template rebind_alloc<cell_type>>
row_cell_array;
84 template <
typename T,
typename CellType>
91 typedef std::vector<cell_type, typename std::allocator_traits<allocator_type>::template rebind_alloc<cell_type>>
row_cell_array;
99 template <
typename T,
typename CellType, u
int32_t Columns,
bool CellsCached = false>
111 typedef std::vector<row, typename std::allocator_traits<allocator_type>::template rebind_alloc<row>>
container_type;
112 typedef typename container_type::iterator
iterator;
119 template <
typename T2,
typename CellType2,
bool CellsCached2 = CellsCached>
126 template <
typename T,
typename CellType, u
int32_t Columns,
bool CellsCached = false>
146 template <
typename T2,
typename CellType2,
bool CellsCached2 = CellsCached>
153 template <
typename T,
typename CellType,
bool CellsCached>
165 typedef std::vector<row, typename std::allocator_traits<allocator_type>::template rebind_alloc<row>>
container_type;
166 typedef typename container_type::iterator
iterator;
173 template <
typename T2,
typename CellType2,
bool CellsCached2 = CellsCached>
180 template <
typename T,
typename CellType,
bool CellsCached>
200 template <
typename T2,
typename CellType2,
bool CellsCached2 = CellsCached>
207 template <
typename T, u
int32_t Columns = 0,
typename CellType = item_cell_data,
typename ContainerTraits = item_flat_container_traits<T, CellType, Columns>>
238 mutable optional_item_cell_info defaultDataInfo;
240 typedef typename container_traits::template rebind<item_model_index::row_type, column_info>::other::row_cell_array column_info_array;
253 return container_traits::is_tree;
257 return static_cast<uint32_t
>(iItems.size());
261 return static_cast<uint32_t
>(iColumns.size());
265 return static_cast<uint32_t
>(
row(aIndex).cells.size());
269 if (iColumns.size() < aColumnIndex + 1u)
270 throw base_type::bad_column_index();
271 return iColumns[aColumnIndex].name;
275 if (iColumns.size() < aColumnIndex + 1u)
276 iColumns.resize(aColumnIndex + 1u);
277 iColumns[aColumnIndex].name = aName;
278 ColumnInfoChanged.trigger(aColumnIndex);
282 return default_cell_info(aColumnIndex).dataType;
286 default_cell_info(aColumnIndex).dataType = aType;
287 ColumnInfoChanged.trigger(aColumnIndex);
291 return default_cell_info(aColumnIndex).dataMin;
295 default_cell_info(aColumnIndex).dataMin = aValue;
296 ColumnInfoChanged.trigger(aColumnIndex);
300 return default_cell_info(aColumnIndex).dataMax;
304 default_cell_info(aColumnIndex).dataMax = aValue;
305 ColumnInfoChanged.trigger(aColumnIndex);
309 return default_cell_info(aColumnIndex).dataStep;
313 default_cell_info(aColumnIndex).dataStep = aValue;
314 ColumnInfoChanged.trigger(aColumnIndex);
329 i_item_model::iterator
begin()
override
333 i_item_model::const_iterator
begin()
const override
337 i_item_model::iterator
end()
override
341 i_item_model::const_iterator
end()
const override
347 if constexpr (container_traits::is_tree)
350 throw base_type::wrong_model_type();
352 i_item_model::const_iterator
sbegin()
const override
354 if constexpr (container_traits::is_tree)
357 throw base_type::wrong_model_type();
359 i_item_model::iterator
send()
override
361 if constexpr (container_traits::is_tree)
364 throw base_type::wrong_model_type();
366 i_item_model::const_iterator
send()
const override
368 if constexpr (container_traits::is_tree)
371 throw base_type::wrong_model_type();
375 if constexpr (container_traits::is_tree)
378 throw base_type::wrong_model_type();
382 if constexpr (container_traits::is_tree)
385 throw base_type::wrong_model_type();
387 bool has_parent(i_item_model::const_iterator aChild)
const override
389 if constexpr (container_traits::is_tree)
392 throw base_type::wrong_model_type();
396 if constexpr (container_traits::is_tree)
399 throw base_type::wrong_model_type();
401 i_item_model::iterator
parent(i_item_model::iterator aChild)
override
403 if constexpr (container_traits::is_tree)
406 throw base_type::wrong_model_type();
408 i_item_model::const_iterator
parent(i_item_model::const_iterator aChild)
const override
410 if constexpr (container_traits::is_tree)
413 throw base_type::wrong_model_type();
417 if constexpr (container_traits::is_tree)
420 throw base_type::wrong_model_type();
422 i_item_model::iterator
sbegin(i_item_model::iterator aParent)
override
424 if constexpr (container_traits::is_tree)
427 throw base_type::wrong_model_type();
429 i_item_model::const_iterator
sbegin(i_item_model::const_iterator aParent)
const override
431 if constexpr (container_traits::is_tree)
434 throw base_type::wrong_model_type();
436 i_item_model::iterator
send(i_item_model::iterator aParent)
override
438 if constexpr (container_traits::is_tree)
441 throw base_type::wrong_model_type();
443 i_item_model::const_iterator
send(i_item_model::const_iterator aParent)
const override
445 if constexpr (container_traits::is_tree)
448 throw base_type::wrong_model_type();
453 if (aIndex.
column() <
row(aIndex).cells.size())
454 return row(aIndex).cells[aIndex.
column()];
455 static const item_cell_data sEmpty;
460 return default_cell_info(aIndex.
column());
465 return iItems.empty();
469 if constexpr (container_traits::is_flat)
470 iItems.reserve(aItemCount);
472 throw base_type::wrong_model_type();
476 if constexpr (container_traits::is_flat)
477 return static_cast<uint32_t
>(iItems.capacity());
479 throw base_type::wrong_model_type();
487 i_item_model::iterator
insert_item(i_item_model::const_iterator aPosition,
value_type const& aValue, item_cell_data
const& aCellData)
override
490 do_insert_cell_data(result, 0, aCellData);
491 ItemAdded.trigger(iterator_to_index(result));
492 ItemChanged.trigger(iterator_to_index(result));
495 i_item_model::iterator
insert_item(i_item_model::const_iterator aPosition, item_cell_data
const& aCellData)
override
497 return insert_item(aPosition,
value_type{}, aCellData);
501 return insert_item(index_to_iterator(aIndex), aValue);
505 return insert_item(index_to_iterator(aIndex), aValue, aCellData);
509 return insert_item(index_to_iterator(aIndex), aCellData);
521 if constexpr (container_traits::is_tree)
524 ItemAdded.trigger(iterator_to_index(result));
528 throw base_type::wrong_model_type();
530 i_item_model::iterator
append_item(i_item_model::const_iterator aParent,
value_type const& aValue, item_cell_data
const& aCellData)
override
533 insert_cell_data(result, 0, aCellData);
536 i_item_model::iterator
append_item(i_item_model::const_iterator aParent, item_cell_data
const& aCellData)
override
538 return append_item(aParent,
value_type(), aCellData);
542 return append_item(index_to_iterator(aIndex), aValue);
546 return append_item(index_to_iterator(aIndex), aValue, aCellData);
550 return append_item(index_to_iterator(aIndex), aCellData);
557 i_item_model::iterator
erase(i_item_model::const_iterator aPosition)
override
560 if constexpr (container_traits::is_tree)
561 while (containerIterator.rbegin() != containerIterator.rend())
563 auto const index = iterator_to_index(aPosition);
564 ItemRemoving.trigger(index);
565 auto result =
base_iterator{ iItems.erase(containerIterator) };
566 ItemRemoved.trigger(index);
571 return erase(index_to_iterator(aIndex));
575 if (do_insert_cell_data(aItem, aColumnIndex, aCellData))
579 ItemChanged.trigger(index);
584 insert_cell_data(index_to_iterator(aIndex), aIndex.
column(), aCellData);
588 update_cell_data(iterator_to_index(aPosition).with_column(aColumnIndex), aCellData);
592 if (std::holds_alternative<string>(aCellData) && std::get<string>(aCellData).empty())
594 update_cell_data(aIndex, {});
597 if (
row(aIndex).cells.size() <= aIndex.
column())
598 row(aIndex).cells.resize(aIndex.
column() + 1u);
599 if (
row(aIndex).cells[aIndex.
column()] == aCellData)
601 row(aIndex).cells[aIndex.
column()] = aCellData;
602 if (default_cell_info(aIndex.
column()).dataType == item_data_type::Unknown)
604 ItemChanged.trigger(aIndex);
607 using base_type::item;
610 return row(aIndex).value;
614 return row(aIndex).value;
626 row_type
const& row(item_model_index
const& aIndex)
const
628 return *
std::next(iItems.begin(), aIndex.row());
630 item_cell_info
const& default_cell_info(item_model_index::column_type aColumnIndex)
const
632 if (iColumns.size() < aColumnIndex + 1)
633 throw base_type::bad_column_index();
634 if (iColumns[aColumnIndex].defaultDataInfo != std::nullopt)
635 return *iColumns[aColumnIndex].defaultDataInfo;
638 static const item_cell_info sZero = {};
642 item_cell_info& default_cell_info(item_model_index::column_type aColumnIndex)
644 if (iColumns.size() < aColumnIndex + 1)
646 iColumns.resize(aColumnIndex + 1);
647 ColumnInfoChanged.trigger(aColumnIndex);
649 if (iColumns[aColumnIndex].defaultDataInfo == std::nullopt)
650 iColumns[aColumnIndex].defaultDataInfo = item_cell_info{};
651 return *iColumns[aColumnIndex].defaultDataInfo;
653 bool do_insert_cell_data(i_item_model::iterator aItem, item_model_index::value_type aColumnIndex, item_cell_data
const& aCellData)
655 if (std::holds_alternative<string>(aCellData) && std::get<string>(aCellData).empty())
656 return do_insert_cell_data(aItem, aColumnIndex, {});
657 bool changed =
false;
658 auto ri = aItem.get<iterator, iterator, sibling_iterator>();
659 if (ri->cells.size() < aColumnIndex + 1)
661 ri->cells.resize(aColumnIndex + 1);
664 if (iColumns.size() < aColumnIndex + 1)
666 iColumns.resize(aColumnIndex + 1);
667 ColumnInfoChanged.trigger(aColumnIndex);
670 if (default_cell_info(aColumnIndex).dataType == item_data_type::Unknown)
672 default_cell_info(aColumnIndex).dataType =
static_cast<item_data_type>(aCellData.index());
675 if (ri->cells[aColumnIndex] != aCellData)
677 ri->cells[aColumnIndex] = aCellData;
683 container_type iItems;
684 column_info_array iColumns;
690 template <
typename T, u
int32_t Columns = 0>
i_item_model::iterator append_item(value_type const &aValue, item_cell_data const &aCellData) override
ContainerTraits container_traits
container_traits::sibling_iterator sibling_iterator
bool has_children(i_item_model::const_iterator aParent) const override
container_type::const_iterator const_iterator
row_cell_array::iterator column_iterator
i_item_model::const_iterator send(i_item_model::const_iterator aParent) const override
void reserve(uint32_t aItemCount) override
container_type::iterator iterator
i_item_model::iterator send() override
i_item_model::iterator sbegin(i_item_model::iterator aParent) override
i_item_model::iterator send(i_item_model::iterator aParent) override
i_item_model::iterator index_to_iterator(item_model_index const &aIndex) override
void insert_cell_data(item_model_index const &aIndex, item_cell_data const &aCellData) override
i_item_model::iterator append_item(item_model_index const &aIndex, value_type const &aValue) override
uint32_t columns() const override
define_declared_event(ColumnInfoChanged, column_info_changed, item_model_index::column_type) define_declared_event(ItemAdded
i_item_model::iterator append_item(item_model_index const &aIndex, value_type const &aValue, item_cell_data const &aCellData) override
item_cell_data const & column_step_value(item_model_index::column_type aColumnIndex) const override
bool has_parent(i_item_model::const_iterator aChild) const override
i_item_model::iterator end() override
value_type & item(item_model_index const &aIndex) override
i_item_model::const_iterator sbegin() const override
bool has_parent(const item_model_index &aChildIndex) const override
uint32_t rows() const override
const item_model_index item_removing
void update_cell_data(item_model_index const &aIndex, item_cell_data const &aCellData) override
i_item_model::iterator append_item(i_item_model::const_iterator aParent, value_type const &aValue, item_cell_data const &aCellData) override
void set_column_max_value(item_model_index::column_type aColumnIndex, item_cell_data const &aValue) override
item_data_type column_data_type(item_model_index::column_type aColumnIndex) const override
item_model_index iterator_to_index(i_item_model::const_iterator aPosition) const override
i_item_model::iterator insert_item(item_model_index const &aIndex, item_cell_data const &aCellData) override
row_cell_array::const_iterator const_column_iterator
i_item_model::iterator append_item(i_item_model::const_iterator aParent, value_type const &aValue) override
container_type::value_type row_type
void set_column_data_type(item_model_index::column_type aColumnIndex, item_data_type aType) override
i_item_model::iterator parent(i_item_model::iterator aChild) override
item_model_index parent(const item_model_index &aChildIndex) const override
uint32_t columns(item_model_index const &aIndex) const override
i_item_model::iterator insert_item(item_model_index const &aIndex, value_type const &aValue) override
uint32_t capacity() const override
const item_cell_info & cell_info(item_model_index const &aIndex) const override
i_item_model::iterator append_item(value_type const &aValue) override
item_cell_data const & cell_data(item_model_index const &aIndex) const override
i_item_model::iterator begin() override
i_item_model::const_iterator send() const override
i_item_model::iterator insert_item(i_item_model::const_iterator aPosition, value_type const &aValue, item_cell_data const &aCellData) override
i_item_model::iterator insert_item(item_model_index const &aIndex, value_type const &aValue, item_cell_data const &aCellData) override
i_item_model::iterator erase(item_model_index const &aIndex) override
bool is_tree() const override
i_item_model::const_iterator index_to_iterator(item_model_index const &aIndex) const override
container_traits::const_sibling_iterator const_sibling_iterator
value_type const & item(item_model_index const &aIndex) const override
container_type const & items() const
i_item_model::iterator append_item(item_model_index const &aIndex, item_cell_data const &aCellData) override
i_item_model::iterator append_item(i_item_model::const_iterator aParent, item_cell_data const &aCellData) override
container_traits::cell_type cell_type
void update_cell_data(i_item_model::const_iterator aPosition, item_model_index::value_type aColumnIndex, item_cell_data const &aCellData) override
void set_column_name(item_model_index::value_type aColumnIndex, std::string const &aName) override
i_item_model::iterator sbegin() override
i_item_model::const_iterator begin() const override
i_item_model::const_iterator sbegin(i_item_model::const_iterator aParent) const override
container_traits::value_type value_type
container_traits::allocator_type allocator_type
container_traits::container_type container_type
std::string const & column_name(item_model_index::value_type aColumnIndex) const override
container_traits::row_cell_array row_cell_array
i_item_model::const_iterator parent(i_item_model::const_iterator aChild) const override
void set_column_min_value(item_model_index::column_type aColumnIndex, item_cell_data const &aValue) override
i_item_model::iterator insert_item(i_item_model::const_iterator aPosition, value_type const &aValue) override
bool has_children(const item_model_index &aParentIndex) const override
void set_column_step_value(item_model_index::column_type aColumnIndex, item_cell_data const &aValue) override
i_item_model::iterator insert_item(i_item_model::const_iterator aPosition, item_cell_data const &aCellData) override
i_item_model::const_iterator end() const override
void insert_cell_data(i_item_model::iterator aItem, item_model_index::value_type aColumnIndex, item_cell_data const &aCellData) override
i_item_model::iterator erase(i_item_model::const_iterator aPosition) override
bool empty() const override
item_cell_data const & column_max_value(item_model_index::column_type aColumnIndex) const override
item_cell_data const & column_min_value(item_model_index::column_type aColumnIndex) const override
std::string name(uint32_t aIndex) const
container_type::const_iterator const_iterator
item_row_traits< T, CellType, 0, CellsCached >::row row
iterator sibling_iterator
std::allocator< value_type > allocator_type
container_type::iterator iterator
const_iterator const_sibling_iterator
const_iterator const_skip_iterator
item_row_traits< T, CellType, 0, CellsCached >::row_cell_array row_cell_array
std::vector< row, typename std::allocator_traits< allocator_type >::template rebind_alloc< row > > container_type
item_row_traits< T, CellType, Columns, CellsCached >::row_cell_array row_cell_array
static constexpr bool is_tree
const_iterator const_skip_iterator
container_type::iterator iterator
const_iterator const_sibling_iterator
container_type::const_iterator const_iterator
static constexpr bool is_flat
item_row_traits< T, CellType, Columns, CellsCached >::row row
iterator sibling_iterator
std::allocator< value_type > allocator_type
std::vector< row, typename std::allocator_traits< allocator_type >::template rebind_alloc< row > > container_type
void set_column(column_type aColumn)
column_type column() const
std::allocator< value_type > allocator_type
std::vector< cell_type, typename std::allocator_traits< allocator_type >::template rebind_alloc< cell_type > > row_cell_array
std::allocator< value_type > allocator_type
std::vector< cell_type, typename std::allocator_traits< allocator_type >::template rebind_alloc< cell_type > > row_cell_array
neolib::vecarray< cell_type, Columns, Columns, neolib::check< neolib::vecarray_overflow >, typename std::allocator_traits< allocator_type >::template rebind_alloc< cell_type > > row_cell_array
std::allocator< value_type > allocator_type
std::allocator< value_type > allocator_type
neolib::vecarray< cell_type, Columns, Columns, neolib::check< neolib::vecarray_overflow >, typename std::allocator_traits< allocator_type >::template rebind_alloc< cell_type > > row_cell_array
std::allocator< value_type > allocator_type
item_row_traits< T, CellType, 0, CellsCached >::row_cell_array row_cell_array
container_type::iterator iterator
item_row_traits< T, CellType, 0, CellsCached >::row row
container_type::const_sibling_iterator const_sibling_iterator
container_type::sibling_iterator sibling_iterator
neolib::tree< row, 64, typename std::allocator_traits< allocator_type >::template rebind_alloc< row > > container_type
container_type::const_iterator const_iterator
container_type::const_skip_iterator const_skip_iterator
container_type::skip_iterator skip_iterator
static constexpr bool is_tree
container_type::const_iterator const_iterator
container_type::sibling_iterator sibling_iterator
std::allocator< value_type > allocator_type
container_type::iterator iterator
container_type::const_sibling_iterator const_sibling_iterator
item_row_traits< T, CellType, Columns, CellsCached >::row_cell_array row_cell_array
container_type::skip_iterator skip_iterator
item_row_traits< T, CellType, Columns, CellsCached >::row row
container_type::const_skip_iterator const_skip_iterator
neolib::tree< row, 64, typename std::allocator_traits< allocator_type >::template rebind_alloc< row > > container_type
static constexpr bool is_flat
virtual void set_alive()=0
void set_destroying() override
basic_iterator< iterator_type::Normal > iterator
basic_iterator< iterator_type::Sibling > sibling_iterator
basic_const_iterator< iterator_type::Skip > const_skip_iterator
basic_const_iterator< iterator_type::Normal > const_iterator
basic_const_iterator< iterator_type::Sibling > const_sibling_iterator
basic_iterator< iterator_type::Skip > skip_iterator
basic_item_model< void * > item_model
basic_item_model< T, Columns, item_cell_data, item_tree_container_traits< T, item_cell_data, Columns > > basic_item_tree_model
it_type next(it_type it, const typename iterator_traits< it_type >::difference_type distance=1)
iterator_traits< it_type >::difference_type distance(const it_type first, const it_type last)
#define define_declared_event(name, declName,...)
item_flat_container_traits< T2, CellType2, Columns, CellsCached2 > other
item_flat_container_traits< T2, CellType2, 0, CellsCached2 > other
item_tree_container_traits< T2, CellType2, Columns, CellsCached2 > other
item_tree_container_traits< T2, CellType2, 0, CellsCached2 > other