File Coverage

lib/Class/STL/Containers.pm
Criterion Covered Total %
statement 308 415 74.2
branch 56 94 59.5
condition 54 96 56.2
subroutine 79 110 71.8
pod n/a
total 497 715 69.5


line stmt bran cond sub pod time code
1             # vim:ts=4 sw=4
2             # ----------------------------------------------------------------------------------------------------
3             # Name : Class::STL::Containers.pm
4             # Created : 22 February 2006
5             # Author : Mario Gaffiero (gaffie)
6             #
7             # Copyright 2006-2007 Mario Gaffiero.
8             #
9             # This file is part of Class::STL::Containers(TM).
10             #
11             # Class::STL::Containers is free software; you can redistribute it and/or modify
12             # it under the terms of the GNU General Public License as published by
13             # the Free Software Foundation; version 2 of the License.
14             #
15             # Class::STL::Containers is distributed in the hope that it will be useful,
16             # but WITHOUT ANY WARRANTY; without even the implied warranty of
17             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18             # GNU General Public License for more details.
19             #
20             # You should have received a copy of the GNU General Public License
21             # along with Class::STL::Containers; if not, write to the Free Software
22             # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23             # ----------------------------------------------------------------------------------------------------
24             # Modification History
25             # When Version Who What
26             # ----------------------------------------------------------------------------------------------------
27             # TO DO:
28             # ----------------------------------------------------------------------------------------------------
29             package Class::STL::Containers;
30             require 5.005_62;
31 7     7   38 use strict;
  7         15  
  7         182  
32 7     7   34 use warnings;
  7         12  
  7         197  
33 7     7   31 use vars qw( $VERSION $BUILD @ISA @EXPORT_OK %EXPORT_TAGS );
  7         13  
  7         868  
34             require Exporter;
35             @ISA = 'Exporter';
36             @EXPORT_OK = qw( vector list deque queue priority_queue stack tree );
37             %EXPORT_TAGS = ( all => [qw( vector list deque queue priority_queue stack tree )] );
38             $VERSION = '0.37';
39             # ----------------------------------------------------------------------------------------------------
40             {
41             package Class::STL::Containers;
42 7     7   48 use vars qw( $AUTOLOAD );
  7         13  
  7         1400  
43             sub AUTOLOAD
44             {
45 41     41   366 (my $func = $AUTOLOAD) =~ s/.*:://;
46 41 100       319 return Class::STL::Containers::Vector->new(@_) if ($func eq 'vector');
47 35 100       1011 return Class::STL::Containers::List->new(@_) if ($func eq 'list');
48 2 50       74 return Class::STL::Containers::Deque->new(@_) if ($func eq 'deque');
49 0 0       0 return Class::STL::Containers::Queue->new(@_) if ($func eq 'queue');
50 0 0       0 return Class::STL::Containers::PriorityQueue->new(@_) if ($func eq 'priority_queue');
51 0 0       0 return Class::STL::Containers::Stack->new(@_) if ($func eq 'stack');
52 0 0       0 return Class::STL::Containers::Tree->new(@_) if ($func eq 'tree');
53             }
54             }
55             # ----------------------------------------------------------------------------------------------------
56             {
57             package Class::STL::Containers::Abstract;
58 7     7   49 use base qw(Class::STL::Element); # container is also an element
  7         13  
  7         2947  
59 7     7   7109 use overload '+' => 'append', '+=' => 'append', '=' => 'clone', '""' => 'str', '==' => 'eq', '!=' => 'ne';
  7         6206  
  7         41  
60 7     7   3639 use Class::STL::Iterators qw(:all);
  7         27  
  7         1373  
61 7     7   43 use UNIVERSAL;
  7         12  
  7         31  
62 7     7   238 use Carp qw(confess);
  7         13  
  7         360  
63             use Class::STL::ClassMembers
64 7         32 Class::STL::ClassMembers::DataMember->new(
65 7     7   38 name => 'element_type', default => 'Class::STL::Element');
  7         13  
66 7     7   39 use Class::STL::ClassMembers::Constructor;
  7         13  
  7         29  
67             # new(named-argument-list);
68             # new(container-ref); -- copy ctor
69             # new(element [, ...]); -- initialise new container with element(s).
70             # new(iterator-start); -- initialise new container with copy of elments from other container.
71             # new(iterator-start, iterator-finish); -- initialise new container with copy of elments from other container.
72             # new(raw-data, [...]); --
73             sub new_extra # static function
74             {
75 52     52   103 my $self = shift;
76 7     7   41 use vars qw(@ISA);
  7         13  
  7         12232  
77 52         217 my @copy_elements;
78             my @copy_iterators;
79 52         0 my @raw_data;
80 52         0 my @params;
81 52         152 while (@_)
82             {
83 249         432 my $p = shift;
84 249 100 100     928 if (!ref($p) && int(@_) && (exists(${$self->members()}{$p}) || $self->can($p)))
    100 66        
    50 100        
    50 66        
      33        
      33        
85             {
86 5         20 shift;
87             }
88             elsif (ref($p) && $p->isa('Class::STL::Iterators::Abstract'))
89             {
90 6         17 CORE::push(@copy_iterators, $p);
91             }
92             elsif (ref($p) && $p->isa(__PACKAGE__))
93             {
94             #? shift; # ??? why???
95             }
96             elsif (ref($p) && $p->isa('Class::STL::Element'))
97             {
98 0         0 CORE::push(@copy_elements, $p);
99             }
100             else {
101 238         1043 CORE::push(@raw_data, $p);
102             }
103             }
104 52 50       1039 confess "element_type (@{[ $self->element_type() ]}) must be derived from Class::STL::Element!"
  0         0  
105             unless (UNIVERSAL::isa($self->element_type(), 'Class::STL::Element'));
106 52         1017 $self->data_type('array');
107 52         1047 $self->data([]); # Array of (base) type Class::STL::Element
108 52         138 foreach (@copy_elements) { $self->push($_); }
  0         0  
109 52         146 while (@raw_data) { $self->push($self->factory(data => shift(@raw_data))); }
  238         633  
110 52 100       136 if (@copy_iterators) {
111 4 100       21 @copy_iterators >= 2
112             ? $self->insert($self->begin(), $copy_iterators[0], $copy_iterators[1])
113             : $self->insert($self->begin(), $copy_iterators[0]);
114             }
115 52         1050 return $self;
116             }
117             sub append # (container-ref) -- append other to this container;
118             {
119 1     1   4 my $self = shift;
120 1         3 my $other = shift;
121 1         4 $self->push($other->to_array());
122 1         3 return $self;
123             }
124             sub factory # (@params) -- construct an element object and return it;
125             {
126 270     270   484 my $self = shift;
127 270 100       5346 return Class::STL::Element->new(@_) if ($self->element_type() eq 'Class::STL::Element');
128 3         5 our %__factfun;
129 3 100       45 if (!exists($__factfun{$self->element_type()}))
130             {
131 1     1   4 $__factfun{$self->element_type()} = eval("
  1         7  
  1         2  
  1         178  
132             {
133 1         8 package @{[ ref($self) ]}\::Factory::__@{[ do{my $f=uc($self->element_type());$f=~s/\W+/_/g;$f} ]};
  1         4  
  1         27  
  1         3  
  1         4  
134             use base qw(Class::STL::Element);
135             sub _FACTORY
136             {
137             my \$self = shift;
138 1         17 return @{[ $self->element_type() ]}\->new(\@_);
139             }
140             }
141 1         5 @{[ ref($self) ]}\::Factory::__@{[ do{my $f=uc($self->element_type());$f=~s/\W+/_/g;$f} ]}->new();
  1         2  
  1         26  
  1         2  
  1         113  
142             ");
143 1 50       7 confess "**Error in eval for @{[ __PACKAGE__ ]} ptr_fun dynamic class creation:\n$@" if ($@);
  0         0  
144             }
145 3         58 return $__factfun{$self->element_type()}->_FACTORY(@_);
146              
147             #< return Class::STL::Element->new(@_) if ($self->element_type() eq 'Class::STL::Element');
148             #< my $e = eval("@{[ $self->element_type() ]}->new(\@_);"); # TODO: pre-gen factory sub code instead!
149             #< confess "**Error in eval for @{[ $self->element_type() ]} factory creation:\n$@" if ($@);
150             #< return $e;
151             }
152             sub push # (element [, ...] ) -- append elements to container...
153             {
154 417     417   760 my $self = shift;
155 417         929 my $curr_sz = $self->size();
156 414   33     679 CORE::push(@{$self->data()}, grep(ref && $_->isa('Class::STL::Element'), @_));
  414         8024  
157 414         1039 return $self->size() - $curr_sz; # number of new elements inserted.
158             }
159             sub pop # (void)
160             {
161 3     3   9 my $self = shift;
162 3         15 CORE::pop(@{$self->data()});
  3         62  
163 3         8 return; # void return
164             }
165             sub top # (void) -- top() and pop() refer to same element.
166             {
167 1     1   3 my $self = shift;
168 1         2 return ${$self->data()}[$self->size()-1];
  1         20  
169             }
170             sub clear # (void)
171             {
172 21     21   72 my $self = shift;
173 21         632 $self->data([]);
174 21         58 return; # void return
175             }
176             sub insert #
177             {
178 229     229   405 my $self = shift;
179 229         315 my $position = shift;
180 229 50 33     1660 confess $self->_insert_errmsg()
      33        
181             unless (defined($position) && ref($position)
182             && $position->isa('Class::STL::Iterators::Abstract'));
183 229         559 my $size = $self->size();
184              
185             # insert(position, iterator-start, iterator-finish);# insert copies
186 229 100 66     3926 if (defined($_[0]) && ref($_[0]) && $_[0]->isa('Class::STL::Iterators::Abstract')
    100 100        
    100 100        
    50 66        
      66        
      66        
      100        
      66        
      66        
      33        
      33        
      33        
187             && defined($_[1]) && ref($_[1]) && $_[1]->isa('Class::STL::Iterators::Abstract'))
188             {
189 3         8 my $iter_start = shift;
190 3         5 my $iter_finish = shift;
191 3 100       7 my $pos = $self->size() ? $position->arr_idx() : 0;
192 3         56 for (my $i = $iter_finish->new($iter_finish); $i >= $iter_start; --$i)
193             {# insert copies
194             $position->can('assign')
195             ? $position->assign($i->p_element()->clone())
196 8 50       43 : CORE::splice(@{$self->data()}, $pos, 0, $i->p_element()->clone());
  8         167  
197             }
198             }
199             # insert(position, iterator-start);# insert copies
200             elsif (defined($_[0]) && ref($_[0]) && $_[0]->isa('Class::STL::Iterators::Abstract'))
201             {
202 2         5 my $iter_start = shift;
203 2         46 for (my $i = $iter_start->new($iter_start); !$i->at_end(); ++$i)
204             {# insert copies
205 5 50 33     27 if ($position->can('assign'))
    50          
206             {
207 0         0 $position->assign($i->p_element()->clone());
208             }
209             #? elsif (!$size || !$position->at_end())
210             elsif (!$size || $position->at_end())
211             {
212 5         23 $self->push($i->p_element()->clone());
213             }
214             else
215             {
216 0         0 CORE::splice(@{$self->data()}, $position->arr_idx(), 0, $i->p_element()->clone());
  0         0  
217 0         0 $position++;
218             }
219             }
220             }
221             # insert(position, element [, ...]); # insert references (not copies)
222             elsif (defined($_[0]) && ref($_[0]) && $_[0]->isa('Class::STL::Element'))
223             {
224 87 100       317 return $position->assign(@_) if ($position->can('assign'));
225             !$size || $position->at_end()
226             ? $self->push(@_)
227 79 100 100     288 : CORE::splice(@{$self->data()}, $position->arr_idx(), 0,
  13   33     253  
228             grep(ref && $_->isa('Class::STL::Element'), @_));
229 79 100       211 $position->first() if (!$size);
230 79         216 $position->next();
231 79         1421 return $position->clone()-1; # iterator points to inserted element
232             }
233             # insert(position, size, element);# insert copies
234             elsif (defined($_[0]) && defined($_[1]) && ref($_[1]) && $_[1]->isa('Class::STL::Element'))
235             {
236 137         299 my $num_repeat = shift;
237 137         240 my $element = shift;
238 137         231 my @elems;
239 137         409 foreach (1..$num_repeat) { CORE::push(@elems, $element->clone()); } # insert copies
  141         3376  
240 137 100       683 return $position->assign(@elems) if ($position->can('assign'));
241             !$size || $position->at_end()
242             ? $self->push(@elems)
243 104 100 100     513 : CORE::splice(@{$self->data()}, $position->arr_idx(), 0, @elems);
  23         596  
244             }
245             else
246             {
247 0         0 confess $self->_insert_errmsg();
248             }
249 109 100       354 $position->first() if (!$size);
250 109         422 $position->next();
251 109         471 return; # void
252             }
253             sub erase # ( iterator | iterator-start, iterator-finish )
254             {
255 39     39   103 my $self = shift;
256 39         73 my $iter_start = shift;
257 39   66     909 my $iter_finish = shift || $iter_start->clone();
258 39         102 my $count=0;
259 39 50       345 CORE::splice(@{$self->data()}, $iter_start->arr_idx(), $count)
  39         834  
260             if (($count=distance($iter_start, $iter_finish)+1) > 0);
261 39 100       178 $iter_start->last() if ($iter_start->at_end());
262 39         371 return $iter_start; # iterator
263             }
264             sub _insert_errmsg
265             {
266 0     0   0 return "@{[ __PACKAGE__ ]}::insert usage:\ninsert( position, element [, ...] );\n"
  0         0  
267             . "insert( position, iterator-start, iterator-finish );\n"
268             . "insert( position, size, element );\n";
269             }
270             sub begin # (void)
271             {
272 253     253   669 my $self = shift;
273 253         1624 return iterator(p_container => $self)->first();
274             }
275             sub end # (void)
276             {
277             # WARNING: end() points to last element unlike C++/STL-end() which points to AFTER last element!!
278             # See examples/iterator.pl for correct iterator traversal example.
279 99     99   270 my $self = shift;
280 99         548 return iterator(p_container => $self)->last();
281             }
282             sub rbegin # (void)
283             {
284 3     3   14 my $self = shift;
285 3         25 return reverse_iterator(p_container => $self)->first();
286             }
287             sub rend # (void)
288             {
289 2     2   5 my $self = shift;
290 2         24 return reverse_iterator(p_container => $self)->last();
291             }
292             sub size # (void)
293             {
294 13200     13200   19784 my $self = shift;
295 13200 50       253540 return defined($self->data()) ? int(@{$self->data()}) : 0;
  13200         248433  
296             }
297             sub empty # return bool
298             {
299 0     0   0 my $self = shift;
300 0 0       0 return $self->size() ? 0 : 1; # 1==true; 0==false
301             }
302             sub to_array # (void)
303             {
304 95     95   333 my $self = shift;
305 95   50     457 my $level = shift || undef;
306              
307 95 50       299 return (@{$self->data()}) # array of data
  95         2232  
308             unless (defined($level));
309              
310 0         0 my @nodes;
311 0         0 foreach (@{$self->data()}) { # traverse tree...
  0         0  
312 0 0       0 ($_->isa('Class::STL::Containers::Abstract'))
313             ? CORE::push(@nodes, $_->to_array($level+1))
314             : CORE::push(@nodes, $_);
315             }
316 0         0 return @nodes;
317             }
318             sub join # (delimiter)
319             {
320 6     6   17 my $self = shift;
321 6   50     28 my $delim = shift || '';
322 6         25 return CORE::join($delim, map($_->print(), $self->to_array())); # string
323             }
324             sub eq # (container-ref)
325             {
326 48     48   122 my $self = shift;
327 48         93 my $other = shift;
328 48 50       124 return 0 unless $self->size() == $other->size();
329 48   66     185 for (my $i1=$self->begin(), my $i2=$other->begin(); !$i1->at_end() && !$i2->at_end(); ++$i1, ++$i2)
330             {
331 530 100       1262 return 0 unless ($i1->p_element()->eq($i2->p_element())); # not equal
332             }
333 47         451 return 1; # containers are equal
334             }
335             sub ne
336             {
337 2     2   3 my $self = shift;
338 2 100       6 return $self->eq(shift) ? 0 : 1;
339             }
340             sub str
341       0     {
342             }
343             }
344             # ----------------------------------------------------------------------------------------------------
345             {
346             package Class::STL::Containers::Vector;
347 7     7   50 use base qw(Class::STL::Containers::Abstract); # vector is also an element
  7         13  
  7         1927  
348 7     7   48 use Class::STL::ClassMembers;
  7         11  
  7         32  
349 7     7   38 use Class::STL::ClassMembers::Constructor;
  7         10  
  7         32  
350 7     7   39 use Class::STL::ClassMembers::Disable qw(push_front);
  7         14  
  7         38  
351             sub push_back # (element [, ...])
352             {
353 23     23   34 my $self = shift;
354 23         170 return $self->push(@_); # number of new elements inserted.
355             }
356             sub pop_back # (void)
357             {
358 1     1   3 my $self = shift;
359 1         12 $self->pop();
360 1         2 return; # void return
361             }
362             sub back # (void)
363             {
364 5     5   12 my $self = shift;
365 5         7 return ${$self->data()}[$self->size()-1]; # element ref
  5         112  
366             }
367             sub front # (void)
368             {
369 5     5   9 my $self = shift;
370 5         6 return ${$self->data()}[0]; # element ref
  5         103  
371             }
372             sub at # (idx)
373             {
374 0     0   0 my $self = shift;
375 0   0     0 my $idx = shift || 0;
376 0         0 return ${$self->data()}[$idx]; # element ref
  0         0  
377             }
378             }
379             # ----------------------------------------------------------------------------------------------------
380             {
381             package Class::STL::Containers::Deque;
382 7     7   48 use base qw(Class::STL::Containers::Vector);
  7         14  
  7         1754  
383 7     7   46 use Class::STL::ClassMembers;
  7         11  
  7         39  
384 7     7   41 use Class::STL::ClassMembers::Constructor;
  7         13  
  7         30  
385             sub push_front # (element [, ...])
386             {
387 27     27   45 my $self = shift;
388 27         46 my $curr_sz = $self->size();
389 27   33     36 unshift(@{$self->data()}, grep(ref && $_->isa("Class::STL::Element"), @_));
  27         373  
390 27         51 return $self->size() - $curr_sz; # number of new elements inserted.
391             }
392             sub pop_front # (void)
393             {
394 1     1   3 my $self = shift;
395 1         2 my $front = shift(@{$self->data()});
  1         19  
396 1         3 return; # void return
397             }
398             }
399             # ----------------------------------------------------------------------------------------------------
400             {
401             package Class::STL::Containers::Queue;
402 7     7   45 use base qw(Class::STL::Containers::Abstract);
  7         14  
  7         1899  
403 7     7   53 use Class::STL::ClassMembers;
  7         12  
  7         33  
404 7     7   38 use Class::STL::ClassMembers::Constructor;
  7         14  
  7         29  
405 7     7   43 use Class::STL::ClassMembers::Disable qw(push_back);
  7         15  
  7         32  
406 7     7   41 use Class::STL::ClassMembers::Disable qw(pop_back);
  7         15  
  7         23  
407             sub back # (void)
408             {
409 0     0   0 my $self = shift;
410 0         0 return $self->SUPER::top();
411             }
412             sub front # (void)
413             {
414 0     0   0 my $self = shift;
415 0         0 return ${$self->data()}[0]; # element ref
  0         0  
416             }
417             sub push # (element [,...]) -- push to back
418             {
419 0     0   0 my $self = shift;
420 0         0 $self->SUPER::push(@_);
421 0         0 return; # void return
422             }
423             sub pop # (void) -- pop from front
424             {
425 0     0   0 my $self = shift;
426 0         0 shift(@{$self->data()});
  0         0  
427 0         0 return; # void return
428             }
429             }
430             # ----------------------------------------------------------------------------------------------------
431             {
432             package Class::STL::Containers::Stack;
433 7     7   48 use base qw(Class::STL::Containers::Abstract);
  7         15  
  7         1517  
434 7     7   47 use Class::STL::ClassMembers;
  7         15  
  7         27  
435 7     7   73 use Class::STL::ClassMembers::Constructor;
  7         16  
  7         33  
436 7     7   43 use Class::STL::ClassMembers::Disable qw(push_back);
  7         14  
  7         32  
437 7     7   52 use Class::STL::ClassMembers::Disable qw(pop_back);
  7         21  
  7         28  
438 7     7   40 use Class::STL::ClassMembers::Disable qw(front);
  7         15  
  7         24  
439             sub top # (void)
440             {
441 0     0   0 my $self = shift;
442 0         0 return $self->SUPER::top();
443             }
444             sub push # (element [,...])
445             {
446 0     0   0 my $self = shift;
447 0         0 $self->SUPER::push(@_);
448             }
449             sub pop # (void)
450             {
451 0     0   0 my $self = shift;
452 0         0 $self->SUPER::pop();
453             }
454             }
455             # ----------------------------------------------------------------------------------------------------
456             {
457             package Class::STL::Containers::Tree;
458 7     7   48 use base qw(Class::STL::Containers::Deque);
  7         14  
  7         2019  
459 7     7   49 use Class::STL::ClassMembers;
  7         17  
  7         30  
460 7     7   42 use Class::STL::ClassMembers::Constructor;
  7         13  
  7         30  
461             sub new_extra
462             {
463 0     0   0 my $self = shift;
464 0         0 $self->element_type(__PACKAGE__);
465 0         0 return $self;
466             }
467             sub to_array # (void)
468             {
469 0     0   0 my $self = shift;
470 0         0 $self->SUPER::to_array(1);
471             }
472             }
473             # ----------------------------------------------------------------------------------------------------
474             {
475             package Class::STL::Containers::List;
476 7     7   47 use base qw(Class::STL::Containers::Deque);
  7         20  
  7         1645  
477 7     7   48 use Class::STL::ClassMembers;
  7         13  
  7         34  
478 7     7   42 use Class::STL::ClassMembers::Constructor;
  7         15  
  7         30  
479 7     7   42 use Class::STL::ClassMembers::Disable qw(at);
  7         16  
  7         32  
480             sub reverse # (void)
481             {
482 2     2   5 my $self = shift;
483 2         5 $self->data([ CORE::reverse(@{$self->data()}) ]);
  2         41  
484             }
485             sub sort # (void | cmp)
486             {
487 0     0   0 my $self = shift;
488 0         0 $self->data([ CORE::sort { $a->cmp($b) } (@{$self->data()}) ]);
  0         0  
  0         0  
489             # sort according to cmp
490             }
491             sub splice
492       0     {
493             #TODO
494             }
495             sub merge
496       0     {
497             #TODO
498             }
499             sub remove # (element)
500       0     {
501             #TODO
502             }
503             sub unique # (void | predicate)
504       0     {
505             #TODO
506             #Erases consecutive elements matching a true condition of the binary_pred. The first occurrence is not removed.
507             }
508             }
509             # ----------------------------------------------------------------------------------------------------
510             {
511             package Class::STL::Element::Priority;
512 7     7   46 use base qw(Class::STL::Element);
  7         32  
  7         689  
513 7     7   47 use Class::STL::ClassMembers qw(priority);
  7         12  
  7         31  
514 7     7   42 use Class::STL::ClassMembers::Constructor;
  7         15  
  7         32  
515             sub cmp
516             {
517 0     0   0 my $self = shift;
518 0         0 my $other = shift;
519 0 0       0 return $self->eq($other) ? 0 : $self->lt($other) ? -1 : 1;
    0          
520             }
521             sub eq # (element)
522             {
523 0     0   0 my $self = shift;
524 0         0 my $other = shift;
525 0         0 return $self->priority() == $other->priority();
526             }
527             sub ne # (element)
528             {
529 0     0   0 my $self = shift;
530 0         0 return !$self->eq(shift);
531             }
532             sub gt # (element)
533             {
534 0     0   0 my $self = shift;
535 0         0 my $other = shift;
536 0         0 return $self->priority() > $other->priority();
537             }
538             sub lt # (element)
539             {
540 0     0   0 my $self = shift;
541 0         0 my $other = shift;
542 0         0 return $self->priority() < $other->priority();
543             }
544             sub ge # (element)
545             {
546 0     0   0 my $self = shift;
547 0         0 my $other = shift;
548 0         0 return $self->priority() >= $other->priority();
549             }
550             sub le # (element)
551             {
552 0     0   0 my $self = shift;
553 0         0 my $other = shift;
554 0         0 return $self->priority() <= $other->priority();
555             }
556             }
557             # ----------------------------------------------------------------------------------------------------
558             {
559             package Class::STL::Containers::PriorityQueue;
560 7     7   47 use base qw(Class::STL::Containers::Vector);
  7         14  
  7         2127  
561 7     7   52 use Class::STL::ClassMembers;
  7         20  
  7         31  
562 7     7   42 use Class::STL::ClassMembers::Constructor;
  7         15  
  7         33  
563 7     7   45 use Class::STL::ClassMembers::Disable qw(push_back);
  7         15  
  7         39  
564 7     7   43 use Class::STL::ClassMembers::Disable qw(pop_back);
  7         14  
  7         25  
565 7     7   43 use Class::STL::ClassMembers::Disable qw(front);
  7         15  
  7         28  
566             sub new_extra
567             {
568 0     0   0 my $self = shift;
569 0         0 $self->element_type('Class::STL::Element::Priority');
570 0         0 return $self;
571             }
572             sub push
573             {
574 0     0   0 my $self = shift;
575 0         0 while (my $d = shift)
576             {
577 0 0 0     0 if (!$self->size() || $d->ge($self->top()))
578             {
579 0         0 $self->SUPER::push($d);
580 0         0 next;
581             }
582 0         0 for (my $i=$self->begin(); !$i->at_end(); ++$i)
583             {
584 0 0       0 if ($i->p_element()->gt($d))
585             {
586 0         0 $self->insert($i, $d);
587 0         0 last;
588             }
589             }
590             }
591             }
592             sub pop
593             {
594 0     0   0 my $self = shift;
595 0         0 $self->SUPER::pop();
596             }
597             sub top
598             {
599 0     0   0 my $self = shift;
600 0         0 return $self->SUPER::top();
601             }
602             sub refresh
603             {
604             # If the priority values were modified then a refresh() is required to re-order the elements.
605 0     0   0 my $self = shift;
606 0         0 $self->data([ CORE::sort { $a->cmp($b) } (@{$self->data()}) ]);
  0         0  
  0         0  
607             # sort according to cmp
608             }
609             }
610             # ----------------------------------------------------------------------------------------------------
611             {
612             package Class::STL::Containers::Set;
613 7     7   57 use base qw(Class::STL::Containers::Abstract);
  7         15  
  7         2103  
614             #TODO
615             }
616             # ----------------------------------------------------------------------------------------------------
617             {
618             package Class::STL::Containers::MultiSet;
619 7     7   48 use base qw(Class::STL::Containers::Set);
  7         15  
  7         2113  
620             #TODO
621             }
622             # ----------------------------------------------------------------------------------------------------
623             {
624             package Class::STL::Containers::Map;
625 7     7   47 use base qw(Class::STL::Containers::Abstract);
  7         16  
  7         1916  
626             #TODO
627             }
628             # ----------------------------------------------------------------------------------------------------
629             {
630             package Class::STL::Containers::MultiMap;
631 7     7   48 use base qw(Class::STL::Containers::Map);
  7         15  
  7         1771  
632             #TODO
633             }
634             # ----------------------------------------------------------------------------------------------------
635             {
636             package Class::STL::Containers::MakeFind;
637 7     7   75 use UNIVERSAL;
  7         19  
  7         37  
638 7     7   257 use Carp qw(cluck confess);
  7         16  
  7         2019  
639             sub new # --> import...
640             {
641 0     0   0 my $proto = shift;
642 0   0     0 my $class = ref($proto) || $proto;
643 0         0 my $self = {};
644 0         0 bless($self, $class);
645 0         0 my $package = (caller())[0];
646 0 0       0 confess "**Error: MakeFind is only available to classes derived from Class::STL::Containers::Abstract!\n"
647             unless UNIVERSAL::isa($package, 'Class::STL::Containers::Abstract');
648 0         0 my $this = $package;
649 0         0 $this =~ s/[:]+/_/g;
650 0         0 my $member_name = shift;
651 0         0 my $code = "
652             sub $package\::find
653             {
654             my \$self = shift;
655             my \$what = shift;
656             return Class::STL::Algorithms::find_if
657             (
658             \$self->begin(), \$self->end(),
659 0         0 $package\::Find@{[ uc($member_name) ]}->new(what => \$what)
660             );
661             }
662             {
663 0         0 package $package\::Find@{[ uc($member_name) ]};
664             use base qw(Class::STL::Utilities::FunctionObject::UnaryFunction);
665             use Class::STL::ClassMembers qw(what);
666             use Class::STL::ClassMembers::Constructor;
667             sub function_operator
668             {
669             my \$self = shift;
670             my \$arg = shift; # element object
671             return \$arg->$member_name() eq \$self->what() ? \$arg : 0;
672             }
673             }";
674 0         0 eval($code);
675 0 0       0 cluck "**MakeFind Error:$@\n$code" if ($@);
676             }
677             }
678             # ----------------------------------------------------------------------------------------------------
679             1;