File Coverage

blib/lib/PDL/Types.pm
Criterion Covered Total %
statement 57 106 53.7
branch 11 28 39.2
condition 1 3 33.3
subroutine 20 34 58.8
pod 6 7 85.7
total 95 178 53.3


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