Changeset 4069
- Timestamp:
- Aug 6, 2021, 12:02:23 PM (11 months ago)
- Location:
- branches/kendall-score
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/kendall-score/test/ranking.cc
r4064 r4069 33 33 void test1(test::Suite& suite) 34 34 { 35 suite.out() << YAT_TEST_PROLOGUE; 35 36 suite.out() << "Constructor(0)\n"; 36 37 utility::Ranking<double> ranking; … … 120 121 void test2(test::Suite& suite) 121 122 { 122 suite.out() << "=== " << __func__ << " ===\n";123 suite.out() << YAT_TEST_PROLOGUE; 123 124 // mimick how Ranking is used in Kendall::score 124 125 utility::Ranking<double> ranking; … … 169 170 170 171 172 void test_copy(test::Suite& suite) 173 { 174 suite.out() << YAT_TEST_PROLOGUE; 175 utility::Ranking<double> ranking; 176 ranking.insert(0); 177 ranking.insert(1); 178 ranking.insert(-1); 179 180 suite.out() << "test copy constructor\n"; 181 utility::Ranking<double> ranking2(ranking); 182 int n = std::distance(ranking.begin(), ranking.end()); 183 if (n != 3) { 184 suite.add(false); 185 suite.err() << "ranking distance: " << n << "\n"; 186 } 187 188 n = std::distance(ranking2.begin(), ranking2.end()); 189 if (n != 3) { 190 suite.add(false); 191 suite.err() << "error: copy constructor failed\n"; 192 suite.err() << "ranking2 distance: " << n << "\n"; 193 for (auto it = ranking2.cbegin(); it!=ranking2.cend(); ++it) 194 suite.err() << "value: " << *it << "\n"; 195 } 196 197 utility::Ranking<double> ranking3; 198 ranking3.insert(10); 199 suite.out() << "test copy assignment\n"; 200 ranking3 = ranking2; 201 n = std::distance(ranking3.begin(), ranking3.end()); 202 if (n != 3) { 203 suite.add(false); 204 suite.err() << "error: assignment failed\n"; 205 suite.err() << "ranking3 distance: " << n << "\n"; 206 } 207 208 suite.out() << "test move constructor\n"; 209 utility::Ranking<double> ranking4(std::move(ranking3)); 210 n = std::distance(ranking4.begin(), ranking4.end()); 211 if (n != 3) { 212 suite.add(false); 213 suite.err() << "error: move constructor failed\n"; 214 suite.err() << "ranking4 distance: " << n << "\n"; 215 } 216 217 suite.out() << "test move assignment\n"; 218 ranking4 = std::move(ranking2); 219 n = std::distance(ranking4.begin(), ranking4.end()); 220 if (n != 3) { 221 suite.add(false); 222 suite.err() << "error: move assignment failed\n"; 223 suite.err() << "ranking4 distance: " << n << "\n"; 224 } 225 } 226 227 171 228 int main(int argc, char* argv[]) 172 229 { … … 175 232 test1(suite); 176 233 test2(suite); 234 test_copy(suite); 177 235 } 178 236 catch (std::exception& e) { -
branches/kendall-score/yat/utility/Ranking.h
r4065 r4069 34 34 #include <memory> 35 35 36 #include <iostream> // debug 36 37 namespace theplu { 37 38 namespace yat { … … 79 80 \brief Copy constructor 80 81 */ 81 Ranking(const Ranking& other) 82 : compare_(other.compare()) 83 { 84 if (!other.empty()) 85 impl_.head_.parent_ = copy(other); 86 } 82 Ranking(const Ranking& other); 87 83 88 84 /** 89 85 \brief move constructor 90 86 */ 91 Ranking(Ranking&& other) = default;87 Ranking(Ranking&& other); 92 88 93 89 /** … … 330 326 ranking::Impl impl_; 331 327 328 void clear(void) 329 { 330 if (size()) { 331 YAT_ASSERT(first_node() != &impl_.head_); 332 erase(first_node()); 333 } 334 impl_.reset(); 335 } 336 337 // return a copy of x but with children and parent set to nullptr. 332 338 ranking::NodeValue<T>* 333 clone_node(const ranking::NodeValue<T>* x) const 334 { 335 YAT_ASSERT(0 && "implement me"); 336 YAT_ASSERT(x); 337 ranking::NodeValue<T>* tmp = new ranking::NodeValue<T>(*x); 338 tmp->left_ = nullptr; 339 tmp->right_ = nullptr; 340 return tmp; 341 } 342 343 344 ranking::NodeValue<T>* copy(const Ranking& other) 345 { 346 YAT_ASSERT(0 && "implement me"); 347 ranking::NodeValue<T>* root = copy(other.first_node(), last_node()); 348 //impl_.left_ = root->left_most(); 349 //impl_.right_ = root->right_most(); 350 //size_ = other.size_; 351 return root; 352 } 353 354 339 clone_node(const ranking::NodeValue<T>* x) const; 340 341 /** 342 copy data in other.Impl_ into impl_ 343 344 Basically copy constructor of Impl but nodes (except for head 345 node) are copied as NodeValue<T> and Impl is not aware of T. 346 */ 347 ranking::NodeValue<T>* copy(const Ranking& other); 348 349 /** 350 Create a copy of root and return it 351 */ 355 352 ranking::NodeValue<T>* 356 copy(const ranking::NodeValue<T>* x, ranking::NodeBase* p) 357 { 358 YAT_ASSERT(0 && "implement me"); 359 ranking::NodeValue<T>* top = clone_node(x); 360 top->parent_ = p; 361 try { 362 if (x->right_) 363 top->right_ = copy(right(x), top); 364 p = top; 365 x = left(x); 366 while (x != 0) { 367 ranking::NodeValue<T>* y = clone_node(x); 368 p->left_ = y; 369 y->parent_ = p; 370 if (x->right_) 371 y->right_ = copy(right(x), y); 372 p = y; 373 x = left(x); 374 } 375 } 376 catch (std::exception& e) { 377 // cleanup 378 erase(top); 379 std::rethrow_exception(std::current_exception()); 380 } 381 return top; 382 } 353 copy(const ranking::NodeValue<T>* root, ranking::NodeBase* h) const; 383 354 384 355 … … 443 414 444 415 // delete x and its offsprings 445 void erase(ranking::NodeValue<T>* x) 446 { 447 YAT_ASSERT(0 && "implement me"); 416 void erase(ranking::NodeValue<T>* x) const 417 { 448 418 while (x) { 449 erase(right(x)); 419 if (x->right_ && x->right_ != &impl_.head_) 420 erase(right(x)); 450 421 ranking::NodeValue<T>* tmp = left(x); 451 422 delete x; … … 533 504 534 505 535 iterator insert(std::unique_ptr<ranking::NodeValue<T>>&& element,536 ranking::NodeBase* parent, ranking::NodeBase*& child)537 {538 YAT_ASSERT(0 && "implement me");539 YAT_ASSERT(parent);540 YAT_ASSERT(child==parent->left_ || child==parent->right_);541 // if child is null, assign element542 if (!child) {543 child = element.release();544 child->parent_ = parent;545 YAT_ASSERT(child==parent->left_ || child==parent->right_);546 ++impl_.node_count_;547 return iterator(child);548 }549 if (compare_(element->value(),550 static_cast<ranking::NodeValue<T>*>(child)->value()))551 return insert(std::move(element), child, child->left_);552 return insert(std::move(element), child, child->right_);553 }554 555 556 506 const_iterator 557 507 lower_bound(const ranking::NodeValue<T>* x, const ranking::NodeBase* y, … … 589 539 const ranking::NodeBase* const root_node(void) const 590 540 { 591 YAT_ASSERT(0 && "implement me");592 541 return impl_.head_.parent_; 593 542 } … … 604 553 return impl_.head_.left_; 605 554 } 555 556 557 const ranking::NodeValue<T>* parent(const ranking::NodeBase* x) const 558 { 559 YAT_ASSERT(x); 560 YAT_ASSERT(x->parent_); 561 YAT_ASSERT(x->parent_ != &impl_.head_); 562 return static_cast<const ranking::NodeValue<T>*>(x->parent_); 563 } 564 565 566 ranking::NodeValue<T>* parent(ranking::NodeBase* x) const 567 { 568 YAT_ASSERT(x); 569 YAT_ASSERT(x->parent_); 570 YAT_ASSERT(x->parent_ != &impl_.head_); 571 return static_cast<ranking::NodeValue<T>*>(x->parent_); 572 } 573 606 574 607 575 /* … … 648 616 return true; 649 617 #endif 650 651 } 652 618 } 653 619 }; 620 621 622 // implementations 623 template<typename T, typename Compare> 624 Ranking<T,Compare>::Ranking(const Ranking& other) 625 : compare_(other.compare()) 626 { 627 if (!other.empty()) 628 root_node() = copy(other); 629 YAT_ASSERT(validate()); 630 } 631 632 633 template<typename T, typename Compare> 634 Ranking<T,Compare>::Ranking(Ranking&& other) 635 : compare_(std::move(other.compare())), impl_(std::move(other.impl_)) 636 { 637 YAT_ASSERT(validate()); 638 } 639 640 641 template<typename T, typename Compare> 642 Ranking<T, Compare>& 643 Ranking<T, Compare>::operator=(const Ranking& other) 644 { 645 if (this != &other) { 646 Ranking tmp(other); 647 *this = std::move(tmp); 648 } 649 return *this; 650 } 651 652 653 template<typename T, typename Compare> 654 Ranking<T, Compare>& 655 Ranking<T, Compare>::operator=(Ranking&& other) 656 { 657 clear(); 658 compare_ = std::move(other.compare_); 659 impl_ = std::move(other.impl_); 660 return *this; 661 } 662 663 664 template<typename T, typename Compare> 665 ranking::NodeValue<T>* Ranking<T,Compare>::copy(const Ranking& other) 666 { 667 YAT_ASSERT(validate()); 668 YAT_ASSERT(impl_.head_.parent_ == nullptr); 669 YAT_ASSERT(other.first_node()); 670 ranking::NodeValue<T>* root = copy(other.first_node(), last_node()); 671 root->parent_ = nullptr; 672 root->right_ = last_node(); 673 last_node()->left_ = root->left_most(); 674 last_node()->parent_ = root; 675 impl_.node_count_ = other.size(); 676 YAT_ASSERT(validate()); 677 return root; 678 } 679 680 681 template<typename T, typename Compare> 682 ranking::NodeValue<T>* 683 Ranking<T,Compare>::copy(const ranking::NodeValue<T>* x, 684 ranking::NodeBase* parent) const 685 { 686 YAT_ASSERT(x); 687 ranking::NodeValue<T>* root = clone_node(x); 688 YAT_ASSERT(root); 689 root->parent_ = parent; 690 try { 691 if (x->right_ && !x->right_->is_head_node()) { 692 YAT_ASSERT(x != right(x)); 693 YAT_ASSERT(x->right_ != &impl_.head_); 694 root->right_ = copy(right(x), root); 695 } 696 697 parent = root; 698 x = left(x); 699 while (x) { 700 ranking::NodeValue<T>* y = clone_node(x); 701 parent->left_ = y; 702 y->parent_ = parent; 703 if (x->right_) { 704 YAT_ASSERT(x->right_ != &impl_.head_); 705 y->right_ = copy(right(x), y); 706 } 707 parent = y; 708 x = left(x); 709 } 710 } 711 catch (std::exception& e) { 712 erase(root); 713 std::rethrow_exception(std::current_exception()); 714 } 715 716 return root; 717 } 718 719 720 template<typename T, typename Compare> 721 ranking::NodeValue<T>* 722 Ranking<T,Compare>::clone_node(const ranking::NodeValue<T>* x) const 723 { 724 YAT_ASSERT(x); 725 ranking::NodeValue<T>* res = new ranking::NodeValue<T>(x->value()); 726 res->left_ = nullptr; 727 res->right_ = nullptr; 728 res->parent_ = nullptr; 729 return res; 730 } 654 731 655 732 }}} // of namespace utility, yat, and theplu -
branches/kendall-score/yat/utility/ranking/Impl.cc
r4064 r4069 39 39 40 40 41 Impl::Impl(Impl&& other)41 Impl::Impl(Impl&& from) 42 42 { 43 assert(0 && "implement me"); 44 if (other.head_.parent_ == nullptr) 45 reset(); 46 else 47 move_data(std::move(other)); 43 reset(); 44 if (from.head_.parent_) 45 move_data(std::move(from)); 46 } 47 48 49 Impl& Impl::operator=(Impl&& rhs) 50 { 51 assert(!head_.parent_); 52 move_data(std::move(rhs)); 53 assert(validate()); 54 return *this; 48 55 } 49 56 … … 51 58 void Impl::move_data(Impl&& from) 52 59 { 53 assert( 0 && "implement me");60 assert(head_.parent_ == nullptr); 54 61 head_.parent_ = from.head_.parent_; 55 62 head_.left_ = from.head_.left_; 56 head_.right_ = from.head_.right_;57 head_.parent_-> parent_ = &head_;63 assert(head_.right_ == &head_); 64 head_.parent_->right_ = &head_; 58 65 node_count_ = from.node_count_; 59 66 from.reset(); 67 assert(validate()); 60 68 } 61 69 -
branches/kendall-score/yat/utility/ranking/Impl.h
r4065 r4069 45 45 Impl(Impl&& other); 46 46 Impl& operator=(const Impl& rhs) = delete; 47 Impl& operator=(Impl&& rhs); 47 48 // Head is the only node with no value. Its parent is the root 48 49 // node and the rest of the tree is in the left branch from the … … 53 54 // typically only called with assert, YAT_ASSERT or similar 54 55 bool validate(void) const; 56 void reset(void); 55 57 private: 56 58 void move_data(Impl&&); 57 void reset(void);58 59 }; 59 60 } // end of namespace ranking -
branches/kendall-score/yat/utility/ranking/Iterator.h
r4065 r4069 34 34 #include <iterator> 35 35 36 #include <iostream> // debug 36 37 namespace theplu { 37 38 namespace yat { … … 64 65 Iterator<T>::Iterator(const NodeBase* node) 65 66 : node_(node) 66 {} 67 { 68 } 67 69 68 70
Note: See TracChangeset
for help on using the changeset viewer.