OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2012 Apple Inc. All rights reserved. | 2 * Copyright (C) 2012 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
689 Set set; | 689 Set set; |
690 int counter = 0; | 690 int counter = 0; |
691 set.add(CountCopy(&counter)); | 691 set.add(CountCopy(&counter)); |
692 | 692 |
693 Set other(set); | 693 Set other(set); |
694 counter = 0; | 694 counter = 0; |
695 set = std::move(other); | 695 set = std::move(other); |
696 EXPECT_EQ(0, counter); | 696 EXPECT_EQ(0, counter); |
697 } | 697 } |
698 | 698 |
| 699 class MoveOnly { |
| 700 public: |
| 701 // kEmpty and kDeleted have special meanings when MoveOnly is used as the ke
y of a hash table. |
| 702 enum { |
| 703 kEmpty = 0, |
| 704 kDeleted = -1, |
| 705 kMovedOut = -2 |
| 706 }; |
| 707 |
| 708 explicit MoveOnly(int value = kEmpty, int id = 0) : m_value(value), m_id(id)
{ } |
| 709 MoveOnly(MoveOnly&& other) |
| 710 : m_value(other.m_value) |
| 711 , m_id(other.m_id) |
| 712 { |
| 713 other.m_value = kMovedOut; |
| 714 other.m_id = 0; |
| 715 } |
| 716 MoveOnly& operator=(MoveOnly&& other) |
| 717 { |
| 718 m_value = other.m_value; |
| 719 m_id = other.m_id; |
| 720 other.m_value = kMovedOut; |
| 721 other.m_id = 0; |
| 722 return *this; |
| 723 } |
| 724 |
| 725 int value() const { return m_value; } |
| 726 // id() is used for distinguishing MoveOnlys with the same value(). |
| 727 int id() const { return m_id; } |
| 728 |
| 729 private: |
| 730 MoveOnly(const MoveOnly&) = delete; |
| 731 MoveOnly& operator=(const MoveOnly&) = delete; |
| 732 |
| 733 int m_value; |
| 734 int m_id; |
| 735 }; |
| 736 |
| 737 struct MoveOnlyHash { |
| 738 static unsigned hash(const MoveOnly& value) { return DefaultHash<int>::Hash:
:hash(value.value()); } |
| 739 static bool equal(const MoveOnly& left, const MoveOnly& right) |
| 740 { |
| 741 return DefaultHash<int>::Hash::equal(left.value(), right.value()); |
| 742 } |
| 743 }; |
| 744 |
| 745 } // anonymous namespace |
| 746 |
| 747 template <> |
| 748 struct DefaultHash<MoveOnly> { |
| 749 using Hash = MoveOnlyHash; |
| 750 }; |
| 751 |
| 752 namespace { |
| 753 |
| 754 template <typename Set> |
| 755 class ListOrLinkedHashSetMoveOnlyTest : public ::testing::Test { }; |
| 756 |
| 757 using MoveOnlySetTypes = ::testing::Types<ListHashSet<MoveOnly>, ListHashSet<Mov
eOnly, 1>, LinkedHashSet<MoveOnly>>; |
| 758 TYPED_TEST_CASE(ListOrLinkedHashSetMoveOnlyTest, MoveOnlySetTypes); |
| 759 |
| 760 TYPED_TEST(ListOrLinkedHashSetMoveOnlyTest, MoveOnlyValue) |
| 761 { |
| 762 using Set = TypeParam; |
| 763 using AddResult = typename Set::AddResult; |
| 764 Set set; |
| 765 { |
| 766 AddResult addResult = set.add(MoveOnly(1, 1)); |
| 767 EXPECT_TRUE(addResult.isNewEntry); |
| 768 EXPECT_EQ(1, addResult.storedValue->value()); |
| 769 EXPECT_EQ(1, addResult.storedValue->id()); |
| 770 } |
| 771 { |
| 772 AddResult addResult = set.add(MoveOnly(1, 111)); |
| 773 EXPECT_FALSE(addResult.isNewEntry); |
| 774 EXPECT_EQ(1, addResult.storedValue->value()); |
| 775 EXPECT_EQ(1, addResult.storedValue->id()); |
| 776 } |
| 777 auto iter = set.find(MoveOnly(1)); |
| 778 ASSERT_TRUE(iter != set.end()); |
| 779 EXPECT_EQ(1, iter->value()); |
| 780 EXPECT_EQ(1, iter->id()); |
| 781 |
| 782 iter = set.find(MoveOnly(2)); |
| 783 EXPECT_TRUE(iter == set.end()); |
| 784 |
| 785 // ListHashSet and LinkedHashSet have several flavors of add(). |
| 786 iter = set.addReturnIterator(MoveOnly(2, 2)); |
| 787 EXPECT_EQ(2, iter->value()); |
| 788 EXPECT_EQ(2, iter->id()); |
| 789 |
| 790 iter = set.addReturnIterator(MoveOnly(2, 222)); |
| 791 EXPECT_EQ(2, iter->value()); |
| 792 EXPECT_EQ(2, iter->id()); |
| 793 |
| 794 { |
| 795 AddResult addResult = set.appendOrMoveToLast(MoveOnly(3, 3)); |
| 796 EXPECT_TRUE(addResult.isNewEntry); |
| 797 EXPECT_EQ(3, addResult.storedValue->value()); |
| 798 EXPECT_EQ(3, addResult.storedValue->id()); |
| 799 } |
| 800 { |
| 801 AddResult addResult = set.prependOrMoveToFirst(MoveOnly(4, 4)); |
| 802 EXPECT_TRUE(addResult.isNewEntry); |
| 803 EXPECT_EQ(4, addResult.storedValue->value()); |
| 804 EXPECT_EQ(4, addResult.storedValue->id()); |
| 805 } |
| 806 { |
| 807 AddResult addResult = set.insertBefore(MoveOnly(4), MoveOnly(5, 5)); |
| 808 EXPECT_TRUE(addResult.isNewEntry); |
| 809 EXPECT_EQ(5, addResult.storedValue->value()); |
| 810 EXPECT_EQ(5, addResult.storedValue->id()); |
| 811 } |
| 812 { |
| 813 iter = set.find(MoveOnly(5)); |
| 814 ASSERT_TRUE(iter != set.end()); |
| 815 AddResult addResult = set.insertBefore(iter, MoveOnly(6, 6)); |
| 816 EXPECT_TRUE(addResult.isNewEntry); |
| 817 EXPECT_EQ(6, addResult.storedValue->value()); |
| 818 EXPECT_EQ(6, addResult.storedValue->id()); |
| 819 } |
| 820 |
| 821 // ... but they don't have any pass-out (like take()) methods. |
| 822 |
| 823 set.remove(MoveOnly(3)); |
| 824 set.clear(); |
| 825 } |
| 826 |
| 827 |
699 } // anonymous namespace | 828 } // anonymous namespace |
700 | 829 |
701 } // namespace WTF | 830 } // namespace WTF |
OLD | NEW |