7 #include <morphio/morphology.h>
8 #include <morphio/properties.h>
9 #include <morphio/types.h>
10 #include <morphio/vector_types.h>
28 inline bool operator==(
const SectionBase& other)
const noexcept;
29 inline bool operator!=(
const SectionBase& other)
const noexcept;
49 uint32_t
id() const noexcept {
return id_; }
52 SectionBase(uint32_t
id,
const std::shared_ptr<Property::Properties>& properties);
54 template <
typename Property>
55 range<const typename Property::Type> get()
const;
59 std::shared_ptr<Property::Properties> properties_;
63 SectionBase<T>::SectionBase(uint32_t
id,
const std::shared_ptr<Property::Properties>& properties)
65 , properties_(properties) {
66 const auto& sections = properties->get<
typename T::SectionId>();
67 if (id_ >= sections.size()) {
69 "Requested section ID (" + std::to_string(id_) +
70 ") is out of array bounds (array size = " + std::to_string(sections.size()) +
")");
73 const auto start =
static_cast<size_t>(sections[id_][0]);
74 const size_t end = id_ == sections.size() - 1
75 ? properties->get<
typename T::PointAttribute>().size()
76 : static_cast<size_t>(sections[id_ + 1][0]);
78 range_ = std::make_pair(start, end);
80 if (range_.second <= range_.first) {
81 std::cerr <<
"Dereferencing broken properties section " << id_
82 <<
"\nSection range: " << range_.first <<
" -> " << range_.second <<
'\n';
87 inline bool SectionBase<T>::operator==(
const SectionBase& other)
const noexcept {
88 return other.id_ == id_ && other.properties_ == properties_;
92 inline bool SectionBase<T>::operator!=(
const SectionBase& other)
const noexcept {
93 return !(*
this == other);
97 template <
typename TProperty>
98 range<const typename TProperty::Type> SectionBase<T>::get()
const {
99 const auto& data = properties_->get<TProperty>();
104 auto ptr_start = data.data() + range_.first;
105 return {ptr_start, range_.second - range_.first};
108 template <
typename T>
110 return properties_->get<
typename T::SectionId>()[id_][1] == -1;
113 template <
typename T>
116 throw MissingParentError(
"Cannot call Section::parent() on a root node (section id=" +
117 std::to_string(id_) +
").");
120 const auto _parent =
static_cast<unsigned int>(
121 properties_->get<
typename T::SectionId>()[id_][1]);
122 return {_parent, properties_};
125 template <
typename T>
127 const auto& section_children = properties_->
children<
typename T::SectionId>();
129 if (section_children.empty()) {
133 const auto it = section_children.find(
static_cast<int>(id_));
134 if (it == section_children.end()) {
138 std::vector<T> result;
139 const std::vector<uint32_t> children = it->second;
140 result.reserve(children.size());
141 for (uint32_t
id : children) {
142 result.push_back(T(
id, properties_));