diff options
Diffstat (limited to 'src/Simplex_tree/include/gudhi/Simplex_tree.h')
-rw-r--r-- | src/Simplex_tree/include/gudhi/Simplex_tree.h | 118 |
1 files changed, 100 insertions, 18 deletions
diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 3ab23c12..13d7372c 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -296,12 +296,81 @@ class Simplex_tree { dimension_(-1) { } /** \brief User-defined copy constructor reproduces the whole tree structure. */ - Simplex_tree(const Simplex_tree& simplex_source) - : null_vertex_(simplex_source.null_vertex_), - root_(nullptr, null_vertex_ , simplex_source.root_.members_), - filtration_vect_(), - dimension_(simplex_source.dimension_) { - auto root_source = simplex_source.root_; + Simplex_tree(const Simplex_tree& complex_source) { +#ifdef DEBUG_TRACES + std::cout << "Simplex_tree copy constructor" << std::endl; +#endif // DEBUG_TRACES + copy_from(complex_source); + } + + /** \brief User-defined move constructor relocates the whole tree structure. + * \exception std::invalid_argument In debug mode, if the complex_source is invalid. + */ + Simplex_tree(Simplex_tree && complex_source) { +#ifdef DEBUG_TRACES + std::cout << "Simplex_tree move constructor" << std::endl; +#endif // DEBUG_TRACES + move_from(complex_source); + + // just need to set dimension_ on source to make it available again + // (filtration_vect_ and members are already set from the move) + complex_source.dimension_ = -1; + } + + /** \brief Destructor; deallocates the whole tree structure. */ + ~Simplex_tree() { + root_members_recursive_deletion(); + } + + /** \brief User-defined copy assignment reproduces the whole tree structure. */ + Simplex_tree& operator= (const Simplex_tree& complex_source) + { +#ifdef DEBUG_TRACES + std::cout << "Simplex_tree copy assignment" << std::endl; +#endif // DEBUG_TRACES + // Self-assignment detection + if (&complex_source != this) { + // We start by deleting root_ if not empty + root_members_recursive_deletion(); + + copy_from(complex_source); + } + return *this; + } + + /** \brief User-defined move assignment relocates the whole tree structure. + * \exception std::invalid_argument In debug mode, if the complex_source is invalid. + */ + Simplex_tree& operator=(Simplex_tree&& complex_source) + { +#ifdef DEBUG_TRACES + std::cout << "Simplex_tree move assignment" << std::endl; +#endif // DEBUG_TRACES + // Self-assignment detection + if (&complex_source != this) { + // root_ deletion in case it was not empty + root_members_recursive_deletion(); + + move_from(complex_source); + } + return *this; + } + /** @} */ // end constructor/destructor + + private: + // Copy from complex_source to "this" + void copy_from(const Simplex_tree& complex_source) { + null_vertex_ = complex_source.null_vertex_; + filtration_vect_.clear(); + dimension_ = complex_source.dimension_; + auto root_source = complex_source.root_; + + // root members copy + root_.members() = Dictionary(boost::container::ordered_unique_range, root_source.members().begin(), root_source.members().end()); + // Needs to reassign children + for (auto& map_el : root_.members()) { + map_el.second.assign_children(&root_); + } rec_copy(&root_, &root_source); } @@ -320,26 +389,38 @@ class Simplex_tree { } } - /** \brief User-defined move constructor moves the whole tree structure. */ - Simplex_tree(Simplex_tree && old) - : null_vertex_(std::move(old.null_vertex_)), - root_(std::move(old.root_)), - filtration_vect_(std::move(old.filtration_vect_)), - dimension_(std::move(old.dimension_)) { - old.dimension_ = -1; - old.root_ = Siblings(nullptr, null_vertex_); + // Move from complex_source to "this" + void move_from(Simplex_tree& complex_source) { + null_vertex_ = std::move(complex_source.null_vertex_); + root_ = std::move(complex_source.root_); + filtration_vect_ = std::move(complex_source.filtration_vect_); + dimension_ = std::move(complex_source.dimension_); + + // Need to update root members (children->oncles and children need to point on the new root pointer) + for (auto& map_el : root_.members()) { + if (map_el.second.children() != &(complex_source.root_)) { + // reset children->oncles with the moved root_ pointer value + map_el.second.children()->oncles_ = &root_; + } else { + // if simplex is of dimension 0, oncles_ shall be nullptr + GUDHI_CHECK(map_el.second.children()->oncles_ == nullptr, + std::invalid_argument("Simplex_tree move constructor from an invalid Simplex_tree")); + // and children points on root_ - to be moved + map_el.second.assign_children(&root_); + } + } } - /** \brief Destructor; deallocates the whole tree structure. */ - ~Simplex_tree() { + // delete all root_.members() recursively + void root_members_recursive_deletion() { for (auto sh = root_.members().begin(); sh != root_.members().end(); ++sh) { if (has_children(sh)) { rec_delete(sh->second.children()); } } + root_.members().clear(); } - /** @} */ // end constructor/destructor - private: + // Recursive deletion void rec_delete(Siblings * sib) { for (auto sh = sib->members().begin(); sh != sib->members().end(); ++sh) { @@ -1035,6 +1116,7 @@ class Simplex_tree { * The Simplex_tree must contain no simplex of dimension bigger than * 1 when calling the method. */ void expansion(int max_dim) { + if (max_dim <= 1) return; dimension_ = max_dim; for (Dictionary_it root_it = root_.members_.begin(); root_it != root_.members_.end(); ++root_it) { |