Set.pm
上传用户:market2
上传日期:2018-11-18
资源大小:18786k
文件大小:4k
源码类别:

外挂编程

开发平台:

Windows_Unix

  1. #########################################################################
  2. #  OpenKore - Indexed set
  3. #  Copyright (c) 2006 OpenKore Team
  4. #
  5. #  This software is open source, licensed under the GNU General Public
  6. #  License, version 2.
  7. #  Basically, this means that you're allowed to modify and distribute
  8. #  this software. However, if you distribute modified versions, you MUST
  9. #  also distribute the source code.
  10. #  See http://www.gnu.org/licenses/gpl.html for the full license.
  11. #########################################################################
  12. ##
  13. # MODULE DESCRIPTION: Indexed set
  14. #
  15. # A set (as in mathematics) is a collection with no duplicate items.
  16. # The Set class implements an indexed set. Not only do items only occur
  17. # once, each item can be accessed by index. So a Set is essentially
  18. # an array with no duplicate items.
  19. #
  20. # <h3>Usage</h3>
  21. # To manipulate a Set, use its methods. You can access items in a Set
  22. # just like you access items in an array reference:
  23. # <pre class="example">
  24. # my $set = new Set();
  25. # $set->add("hello");
  26. # $set->add("world");
  27. # $set->add("hello");   # Has no effect. "hello" is already in the set.
  28. #
  29. # foreach my $item (@{$set}) {
  30. #     do_something($item);
  31. # }
  32. #
  33. # $set->[0];            # "hello"
  34. # $set->get(0);         # "hello"
  35. # $set->has("hello");   # 1 (true)
  36. # $set->has("foo");     # undef (false)
  37. #
  38. # $set->remove("hello");
  39. # $set->has("hello");   # undef (false)
  40. # </pre>
  41. #
  42. # However, <b>do not</b> manipulate a Set like it's an array. The
  43. # following will result in corruption of the Set:
  44. # <pre class="example">
  45. # delete $set->[0];
  46. # @{$set} = ();
  47. # splice @{$set}, 1, 1;
  48. # </pre>
  49. #
  50. # <h3>How items are considered equal</h3>
  51. # Two items are considered equal if their strings are the same.
  52. # That is, $a and $b are considered equal if:
  53. # <pre class="example">
  54. # "$a" eq "$b"
  55. # </pre>
  56. package Set;
  57. use strict;
  58. use Scalar::Util;
  59. use overload '@{}' => &getArray;
  60. use overload '[]' => &get;
  61. use overload '""' => &_toString;
  62. ##
  63. # Set Set->new([elements...])
  64. # elements: The elements to add to this set.
  65. #
  66. # Create a new Set, possibly with predefined elements.
  67. sub new {
  68. my $class = shift;
  69. my $self = {
  70. # The items themselves.
  71. items => [],
  72. # Maps items to their index in the items array.
  73. keys => {}
  74. };
  75. $self = bless $self, $class;
  76. foreach my $item (@_) {
  77. $self->add($item);
  78. }
  79. return $self;
  80. }
  81. ##
  82. # void $set->add(item)
  83. # Requires: defined($item)
  84. # Ensures: $self->has($item)
  85. #
  86. # Add $item to the set if it isn't already in the set.
  87. sub add {
  88. my ($self, $item) = @_;
  89. if (!$self->has($item)) {
  90. push @{$self->{items}}, $item;
  91. $self->{keys}{$item} = $#{$self->{items}};
  92. }
  93. }
  94. ##
  95. # void $set->remove(item)
  96. # Requires: defined($item)
  97. # Ensures: !$self->has($item)
  98. #
  99. # Removes $item from the set if it's there.
  100. sub remove {
  101. my ($self, $item) = @_;
  102. if ($self->has($item)) {
  103. my $index = $self->{keys}{$item};
  104. splice(@{$self->{items}}, $index, 1);
  105. delete $self->{keys}{$item};
  106. for (my $i = $index; $i < @{$self->{items}}; $i++) {
  107. my $item = $self->{items}[$i];
  108. $self->{keys}{$item}--;
  109. }
  110. }
  111. }
  112. ##
  113. # void $set->clear()
  114. # Ensures: @{$self} == 0
  115. #
  116. # Remove all items in the set.
  117. sub clear {
  118. my ($self) = @_;
  119. $self->{items} = [];
  120. $self->{keys} = {};
  121. }
  122. ##
  123. # $set->get(int index)
  124. # Requires: 0 <= $index < @{$set}
  125. #
  126. # Returns the item at the specified index.
  127. sub get {
  128. my ($self, $index) = @_;
  129. return $self->{items}[$index];
  130. }
  131. ##
  132. # boolean $set->has(item)
  133. #
  134. # Check whether $item is in the set.
  135. sub has {
  136. my ($self, $item) = @_;
  137. return exists $self->{keys}{$item};
  138. }
  139. ##
  140. # int $set->size()
  141. # Ensures: result >= 0
  142. #
  143. # Returns the number of elements in this set.
  144. sub size {
  145. return scalar(@{$_[0]->{items}});
  146. }
  147. ##
  148. # Array $set->getArray()
  149. # Ensures:
  150. #     defined(result)
  151. #     for all $element in result: defined($element)
  152. #
  153. # Return the set's internal array. You must not manipulate this array.
  154. sub getArray {
  155. return $_[0]->{items};
  156. }
  157. ##
  158. # Set $set->deepCopy()
  159. # Ensures: defined(result)
  160. #
  161. # Create a deep copy of this set. The items themselves are not copied.
  162. sub deepCopy {
  163. my ($self) = @_;
  164. my $copy = new Set();
  165. $copy->{items} = [ @{$self->{items}} ];
  166. $copy->{keys} = { %{$self->{keys}} };
  167. return $copy;
  168. }
  169. sub _toString {
  170. return sprintf("%s(0x%x)",
  171. Scalar::Util::blessed($_[0]),
  172. Scalar::Util::refaddr($_[0]));
  173. }
  174. 1;