File Coverage

blib/lib/PDLA/Types.pm
Criterion Covered Total %
statement 56 103 54.3
branch 10 28 35.7
condition 1 3 33.3
subroutine 20 31 64.5
pod 6 7 85.7
total 93 172 54.0


line stmt bran cond sub pod time code
1              
2             ### Generated from Types.pm.PL automatically - do not modify! ###
3              
4             package PDLA::Types;
5             require Exporter;
6 79     79   570 use Carp;
  79         153  
  79         149255  
7              
8              
9             @EXPORT = qw( $PDLA_B $PDLA_S $PDLA_US $PDLA_L $PDLA_IND $PDLA_LL $PDLA_F $PDLA_D
10             @pack %typehash );
11              
12             @EXPORT_OK = (@EXPORT, qw/types ppdefs typesrtkeys mapfld typefld/);
13             %EXPORT_TAGS = (
14             All=>[@EXPORT,qw/types ppdefs typesrtkeys mapfld typefld/],
15             );
16              
17             @ISA = qw( Exporter );
18              
19              
20              
21             # Data types/sizes (bytes) [must be in order of complexity]
22             # Enum
23             ( $PDLA_B, $PDLA_S, $PDLA_US, $PDLA_L, $PDLA_IND, $PDLA_LL, $PDLA_F, $PDLA_D ) = (0..7);
24             # Corresponding pack types
25             @pack= qw/C* s* S* l* q* q* f* d*/;
26             @names= qw/PDLA_B PDLA_S PDLA_US PDLA_L PDLA_IND PDLA_LL PDLA_F PDLA_D/;
27              
28             %PDLA::Types::typehash = (
29             PDLA_B =>
30             {
31             'convertfunc' => 'byte',
32             'ctype' => 'PDLA_Byte',
33             'defbval' => 'UCHAR_MAX',
34             'ioname' => 'byte',
35             'numval' => 0,
36             'ppforcetype' => 'byte',
37             'ppsym' => 'B',
38             'realctype' => 'unsigned char',
39             'sym' => 'PDLA_B',
40             'usenan' => 0
41             }
42             ,
43             PDLA_S =>
44             {
45             'convertfunc' => 'short',
46             'ctype' => 'PDLA_Short',
47             'defbval' => 'SHRT_MIN',
48             'ioname' => 'short',
49             'numval' => 1,
50             'ppforcetype' => 'short',
51             'ppsym' => 'S',
52             'realctype' => 'short',
53             'sym' => 'PDLA_S',
54             'usenan' => 0
55             }
56             ,
57             PDLA_US =>
58             {
59             'convertfunc' => 'ushort',
60             'ctype' => 'PDLA_Ushort',
61             'defbval' => 'USHRT_MAX',
62             'ioname' => 'ushort',
63             'numval' => 2,
64             'ppforcetype' => 'ushort',
65             'ppsym' => 'U',
66             'realctype' => 'unsigned short',
67             'sym' => 'PDLA_US',
68             'usenan' => 0
69             }
70             ,
71             PDLA_L =>
72             {
73             'convertfunc' => 'long',
74             'ctype' => 'PDLA_Long',
75             'defbval' => 'INT_MIN',
76             'ioname' => 'long',
77             'numval' => 3,
78             'ppforcetype' => 'int',
79             'ppsym' => 'L',
80             'realctype' => 'int',
81             'sym' => 'PDLA_L',
82             'usenan' => 0
83             }
84             ,
85             PDLA_IND =>
86             {
87             'convertfunc' => 'indx',
88             'ctype' => 'PDLA_Indx',
89             'defbval' => 'LONG_MIN',
90             'ioname' => 'indx',
91             'numval' => 4,
92             'ppforcetype' => 'indx',
93             'ppsym' => 'N',
94             'realctype' => 'long',
95             'sym' => 'PDLA_IND',
96             'usenan' => 0
97             }
98             ,
99             PDLA_LL =>
100             {
101             'convertfunc' => 'longlong',
102             'ctype' => 'PDLA_LongLong',
103             'defbval' => 'LONG_MIN',
104             'ioname' => 'longlong',
105             'numval' => 5,
106             'ppforcetype' => 'longlong',
107             'ppsym' => 'Q',
108             'realctype' => 'long',
109             'sym' => 'PDLA_LL',
110             'usenan' => 0
111             }
112             ,
113             PDLA_F =>
114             {
115             'convertfunc' => 'float',
116             'ctype' => 'PDLA_Float',
117             'defbval' => '-FLT_MAX',
118             'ioname' => 'float',
119             'numval' => 6,
120             'ppforcetype' => 'float',
121             'ppsym' => 'F',
122             'realctype' => 'float',
123             'sym' => 'PDLA_F',
124             'usenan' => 1
125             }
126             ,
127             PDLA_D =>
128             {
129             'convertfunc' => 'double',
130             'ctype' => 'PDLA_Double',
131             'defbval' => '-DBL_MAX',
132             'ioname' => 'double',
133             'numval' => 7,
134             'ppforcetype' => 'double',
135             'ppsym' => 'D',
136             'realctype' => 'double',
137             'sym' => 'PDLA_D',
138             'usenan' => 1
139             }
140             ,
141             ); # end typehash definition
142              
143             # Cross-reference by common names
144             %PDLA::Types::typenames = ();
145             for my $k(keys %PDLA::Types::typehash) {
146             my $n = $PDLA::Types::typehash{$k}->{'numval'};
147             $PDLA::Types::typenames{$k} = $n;
148             $PDLA::Types::typenames{$n} = $n;
149             $PDLA::Types::typenames{$PDLA::Types::typehash{$k}->{ioname}} = $n;
150             $PDLA::Types::typenames{$PDLA::Types::typehash{$k}->{ctype}} = $n;
151             }
152              
153              
154             =head1 NAME
155              
156             PDLA::Types - define fundamental PDLA Datatypes
157              
158             =head1 SYNOPSIS
159              
160             use PDLA::Types;
161              
162             $pdl = ushort( 2.0, 3.0 );
163             print "The actual c type used to store ushort's is '" .
164             $pdl->type->realctype() . "'\n";
165             The actual c type used to store ushort's is 'unsigned short'
166              
167             =head1 DESCRIPTION
168              
169             Internal module - holds all the PDLA Type info. The type info can be
170             accessed easily using the C object returned by
171             the L method.
172              
173             Skip to the end of this document to find out how to change
174             the set of types supported by PDLA.
175              
176             =head1 FUNCTIONS
177              
178             A number of functions are available for module writers
179             to get/process type information. These are used in various
180             places (e.g. C, C) to generate the
181             appropriate type loops, etc.
182              
183             =head2 typesrtkeys
184              
185             =for ref
186              
187             Returns an array of keys of typehash sorted in order of type complexity
188              
189             =for example
190              
191             pdla> @typelist = PDLA::Types::typesrtkeys;
192             pdla> print @typelist;
193             PDLA_B PDLA_S PDLA_US PDLA_L PDLA_IND PDLA_LL PDLA_F PDLA_D
194              
195             =cut
196              
197             sub typesrtkeys {
198 266     266 1 1616 return sort {$typehash{$a}->{numval} <=> $typehash{$b}->{numval}}
  4193         7384  
199             keys %typehash;
200             }
201              
202             =head2 ppdefs
203              
204             =for ref
205              
206             Returns an array of pp symbols for all known types
207              
208             =for example
209              
210             pdla> @ppdefs = PDLA::Types::ppdefs
211             pdla> print @ppdefs;
212             B S U L N Q F D
213              
214             =cut
215              
216             sub ppdefs {
217 3     3 1 10 return map {$typehash{$_}->{ppsym}} typesrtkeys;
  24         54  
218             }
219              
220             =head2 typefld
221              
222             =for ref
223              
224             Returns specified field (C<$fld>) for specified type (C<$type>)
225             by querying type hash
226              
227             =for usage
228              
229             PDLA::Types::typefld($type,$fld);
230              
231             =for example
232              
233             pdla> print PDLA::Types::typefld('PDLA_IND',realctype)
234             long
235              
236             =cut
237              
238             sub typefld {
239 2760     2760 1 4358 my ($type,$fld) = @_;
240 2760 50       4853 croak "unknown type $type" unless exists $typehash{$type};
241             croak "unknown field $fld in type $type"
242 2760 50       4994 unless exists $typehash{$type}->{$fld};
243 2760         6231 return $typehash{$type}->{$fld};
244             }
245              
246             =head2 mapfld
247              
248             Map a given source field to the corresponding target field by
249             querying the type hash. This gives you a way to say, "Find the type
250             whose C<$in_key> is equal to C<$value>, and return that type's value
251             for C<$out_key>. For example:
252              
253             # Does byte type use nan?
254             $uses_nan = PDLA::Types::mapfld(byte => 'ppforcetype', 'usenan');
255             # Equivalent:
256             $uses_nan = byte->usenan;
257            
258             # What is the actual C type for the value that we call 'long'?
259             $type_name = PDLA::Types::mapfld(long => 'convertfunc', 'realctype');
260             # Equivalent:
261             $type_name = long->realctype;
262              
263             As you can see, the equivalent examples are much shorter and legible, so you
264             should only use mapfld if you were given the type index (in which case the
265             actual type is not immediately obvious):
266              
267             $type_index = 4;
268             $type_name = PDLA::Types::mapfld($type_index => numval, 'realctype');
269              
270             =cut
271              
272             sub mapfld {
273 4     4 1 10 my ($type,$src,$trg) = @_;
274 4         8 my @keys = grep {$typehash{$_}->{$src} eq $type} typesrtkeys;
  32         70  
275 4 50       34 return @keys > 0 ? $typehash{$keys[0]}->{$trg} : undef;
276             }
277              
278             =head2 typesynonyms
279              
280             =for ref
281              
282             return type related synonym definitions to be included in pdl.h .
283             This routine must be updated to include new types as required.
284             Mostly the automatic updating should take care of the vital
285             things.
286              
287             =cut
288              
289             sub typesynonyms {
290             my $add = join "\n",
291 0         0 map {"#define PDLA_".typefld($_,'ppsym')." ".typefld($_,'sym')}
292 0     0 1 0 grep {"PDLA_".typefld($_,'ppsym') ne typefld($_,'sym')} typesrtkeys;
  0         0  
293 0         0 print "adding...\n$add\n";
294 0         0 return "$add\n";
295             }
296              
297             =head2 datatypes_header
298              
299             =for ref
300              
301             return C header text for F and F.
302              
303             =cut
304              
305             sub datatypes_header {
306 0     0 1 0 require Config;
307 0         0 $PDLA_Indx_type = $Config::Config{'ivtype'};
308 0 0       0 warn "Using new 64bit index support\n" if $Config::Config{'ivsize'}==8;
309              
310 0         0 my $anyval_union = '';
311 0         0 my $enum = 'PDLA_INVALID=-1, ';
312 0         0 my $typedefs = '';
313 0         0 for (sort { $typehash{$a}{'numval'}<=>$typehash{$b}{'numval'} } keys %typehash) {
  0         0  
314 0         0 $enum .= $typehash{$_}{'sym'}.", ";
315 0         0 $anyval_union .= " $typehash{$_}{'ctype'} $typehash{$_}{'ppsym'};\n";
316 0         0 $typedefs .= "typedef $typehash{$_}{'realctype'} $typehash{$_}{'ctype'};\n";
317             }
318 0         0 chop $enum;
319 0         0 chop $enum;
320              
321 0         0 $typedefs .= "typedef struct {\n pdl_datatypes type;\n union {\n";
322 0         0 $typedefs .= $anyval_union;
323 0         0 $typedefs .= " } value;\n} PDLA_Anyval;\n";
324              
325 0         0 my $indx_type = typefld('PDLA_IND','realctype');
326 0         0 $typedefs .= '#define IND_FLAG ';
327 0 0       0 if ($indx_type eq 'long'){
    0          
328 0         0 $typedefs .= qq|"ld"|;
329             } elsif ($indx_type eq 'long long'){
330 0         0 $typedefs .= qq|"lld"|;
331             } else {
332 0         0 $typedefs .= qq|"d"|;
333             }
334 0         0 $typedefs .= "\n\n";
335              
336 0         0 my $PDLA_DATATYPES = <<"EOD";
337              
338             /*****************************************************************************/
339             /*** This section of .h file generated automatically by ***/
340             /*** PDLA::Types::datatypes_header() - don't edit manually ***/
341              
342             /* Data types/sizes [must be in order of complexity] */
343              
344             typedef enum { $enum } pdl_datatypes;
345              
346             /* Define the pdl data types */
347              
348             $typedefs
349              
350             /* typedef $PDLA_Indx_type PDLA_Indx; */
351              
352             /*****************************************************************************/
353              
354             EOD
355              
356 0         0 $PDLA_DATATYPES .= "\n".typesynonyms()."\n";
357 0         0 $PDLA_DATATYPES;
358             }
359              
360             =head1 PDLA::Type OBJECTS
361              
362             This module declares one class - C - objects of this class
363             are returned by the L method of a piddle. It has
364             several methods, listed below, which provide an easy way to access
365             type information:
366              
367             Additionally, comparison and stringification are overloaded so that
368             you can compare and print type objects, e.g.
369              
370             $nofloat = 1 if $pdl->type < float;
371             die "must be double" if $type != double;
372              
373             For further examples check again the
374             L method.
375              
376             =over 4
377              
378             =item enum
379              
380             Returns the number representing this datatype (see L).
381              
382             =item symbol
383              
384             Returns one of 'PDLA_B', 'PDLA_S', 'PDLA_US', 'PDLA_L', 'PDLA_IND', 'PDLA_LL',
385             'PDLA_F' or 'PDLA_D'.
386              
387             =item ctype
388              
389             Returns the macro used to represent this type in C code (eg 'PDLA_Long').
390              
391             =item ppsym
392              
393             The letter used to represent this type in PP code code (eg 'U' for L).
394              
395             =item realctype
396              
397             The actual C type used to store this type.
398              
399             =item shortctype
400              
401             The value returned by C without the 'PDLA_' prefix.
402              
403             =item badvalue
404              
405             The special numerical value used to represent bad values for this type.
406             See L for more details.
407              
408             =cut
409              
410              
411             =item orig_badvalue
412              
413             The default special numerical value used to represent bad values for this
414             type. (You can change the value that represents bad values for each type
415             during runtime.) See the
416             L for more details.
417              
418             =cut
419              
420              
421             =back
422              
423             =cut
424              
425             {
426             package PDLA::Type;
427             sub new {
428 1071     1071   2010 my($type,$val) = @_;
429 1071 50       2169 if("PDLA::Type" eq ref $val) { return bless [@$val],$type; }
  0         0  
430 1071 50 33     2235 if(ref $val and $val->isa(PDLA)) {
431 0 0       0 if($val->getndims != 0) {
432 0         0 PDLA::Core::barf(
433             "Can't make a type out of non-scalar piddle $val!");
434             }
435 0         0 $val = $val->at;
436             }
437 1071 50       1831 PDLA::Core::barf("Can't make a type out of non-scalar $val!".
438             (ref $val)."!") if ref $val;
439              
440 1071 50       2250 if(length($PDLA::Types::typenames{$val})) {
441 1071         3545 $val =~ s/^\s*//o;
442 1071         3211 $val =~ s/\s*$//o;
443 1071         4135 return bless [$PDLA::Types::typenames{$val}],$type;
444             } else {
445             die("Unknown type string '$val' (should be one of ".
446 0         0 join(",",map { $PDLA::Types::typehash{$_}->{ioname} } @names).
  0         0  
447             ")\n");
448             }
449             }
450              
451 300     300   1658 sub enum { return $_[0]->[0]; }
452 46     46   96 sub symbol { return $PDLA::Types::names[ $_[0]->enum ]; }
453             sub PDLA::Types::types { # return all known types as type objects
454 95     95 0 193 map { new PDLA::Type PDLA::Types::typefld($_,'numval') }
  760         1349  
455             PDLA::Types::typesrtkeys();
456             }
457              
458             sub ctype {
459 34     34   94 return $PDLA::Types::typehash{$_[0]->symbol}->{ctype};
460             }
461             sub ppsym {
462 0     0   0 return $PDLA::Types::typehash{$_[0]->symbol}->{ppsym};
463             }
464             sub realctype {
465 0     0   0 return $PDLA::Types::typehash{$_[0]->symbol}->{realctype};
466             }
467             sub ppforcetype {
468 0     0   0 return $PDLA::Types::typehash{$_[0]->symbol}->{ppforcetype};
469             }
470             sub convertfunc {
471 0     0   0 return $PDLA::Types::typehash{$_[0]->symbol}->{convertfunc};
472             }
473             sub sym {
474 0     0   0 return $PDLA::Types::typehash{$_[0]->symbol}->{sym};
475             }
476             sub numval {
477 0     0   0 return $PDLA::Types::typehash{$_[0]->symbol}->{numval};
478             }
479             sub usenan {
480 7     7   21 return $PDLA::Types::typehash{$_[0]->symbol}->{usenan};
481             }
482             sub ioname {
483 0     0   0 return $PDLA::Types::typehash{$_[0]->symbol}->{ioname};
484             }
485             sub defbval {
486 0     0   0 return $PDLA::Types::typehash{$_[0]->symbol}->{defbval};
487             }
488              
489 79     79   730 no strict 'refs';
  79         184  
  79         13795  
490             sub badvalue {
491 87     87   291 my ( $self, $val ) = @_;
492 87         296 my $name = "PDLA::_badvalue_int" . $self->enum();
493 87 100       238 if ( defined $val ) { return &{$name}( $val )->sclr; }
  6         10  
  6         41  
494 81         126 else { return &{$name}( undef )->sclr; }
  81         863  
495             }
496              
497             sub orig_badvalue {
498 5     5   11 my $self = shift;
499 5         12 my $name = "PDLA::_default_badvalue_int" . $self->enum();
500 5         10 return &{$name}()->sclr;
  5         40  
501             }
502 79     79   713 use strict 'refs';
  79         222  
  79         20853  
503              
504              
505 34     34   78 sub shortctype { my $txt = $_[0]->ctype; $txt =~ s/PDLA_//; return $txt; }
  34         98  
  34         197  
506              
507             # make life a bit easier
508             use overload (
509 24     24   66 "\"\"" => sub { lc $_[0]->shortctype },
510 23     23   330 "eq" => sub { my($self, $other, $swap) = @_;
511 23         42 return ("$self" eq $other);
512             },
513 0     0   0 "cmp" => sub { my($self, $other, $swap) = @_;
514 0 0       0 return ($swap ? $other cmp "$self" : "$self" cmp $other);
515             },
516 11 50   11   50 "<=>" => sub { $_[2] ? $_[1]->enum <=> $_[0]->enum :
517             $_[0]->enum <=> $_[1]->enum },
518 79     79   89046 );
  79         95055  
  79         1019  
519              
520              
521             } # package: PDLA::Type
522             # Return
523             1;
524              
525             __END__