File Coverage

blib/lib/PDL/Types.pm
Criterion Covered Total %
statement 57 103 55.3
branch 11 28 39.2
condition 1 3 33.3
subroutine 20 31 64.5
pod 6 7 85.7
total 95 172 55.2


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 125     125   832 use Carp;
  125         244  
  125         255203  
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 373     373 1 69850 return sort {$typehash{$a}->{numval} <=> $typehash{$b}->{numval}}
  8622         14139  
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 10 return map {$typehash{$_}->{ppsym}} typesrtkeys;
  30         63  
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 5149     5149 1 8977 my ($type,$fld) = @_;
268 5149 50       8575 croak "unknown type $type" unless exists $typehash{$type};
269             croak "unknown field $fld in type $type"
270 5149 50       8879 unless exists $typehash{$type}->{$fld};
271 5149         11619 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 10 my ($type,$src,$trg) = @_;
302 4         8 my @keys = grep {$typehash{$_}->{$src} eq $type} typesrtkeys;
  40         71  
303 4 50       24 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 3010     3010   6335 my($type,$val) = @_;
457 3010 100       6751 if("PDL::Type" eq ref $val) { return bless [@$val],$type; }
  1         12  
458 3009 50 33     6431 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 3009 50       5290 PDL::Core::barf("Can't make a type out of non-scalar $val!".
466             (ref $val)."!") if ref $val;
467              
468 3009 50       7469 if(length($PDL::Types::typenames{$val})) {
469 3009         12098 $val =~ s/^\s*//o;
470 3009         9754 $val =~ s/\s*$//o;
471 3009         13990 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 1943     1943   6965 sub enum { return $_[0]->[0]; }
480 1404     1404   2698 sub symbol { return $PDL::Types::names[ $_[0]->enum ]; }
481             sub PDL::Types::types { # return all known types as type objects
482 99     99 0 235 map { new PDL::Type PDL::Types::typefld($_,'numval') }
  990         1695  
483             PDL::Types::typesrtkeys();
484             }
485              
486             sub ctype {
487 1376     1376   2976 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   17 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              
517 125     125   1381 no strict 'refs';
  125         313  
  125         24472  
518             sub badvalue {
519 91     91   187 my ( $self, $val ) = @_;
520 91         217 my $name = "PDL::_badvalue_int" . $self->enum();
521 91 100       250 if ( defined $val ) { return &{$name}( $val )->sclr; }
  6         9  
  6         41  
522 85         157 else { return &{$name}( undef )->sclr; }
  85         945  
523             }
524              
525             sub orig_badvalue {
526 5     5   11 my $self = shift;
527 5         11 my $name = "PDL::_default_badvalue_int" . $self->enum();
528 5         8 return &{$name}()->sclr;
  5         41  
529             }
530 125     125   986 use strict 'refs';
  125         358  
  125         37152  
531              
532              
533 1376     1376   2781 sub shortctype { my $txt = $_[0]->ctype; $txt =~ s/PDL_//; return $txt; }
  1376         3653  
  1376         9638  
534              
535             # make life a bit easier
536             use overload (
537 1365     1365   8183 "\"\"" => sub { lc $_[0]->shortctype },
538 1161     1161   2824 "eq" => sub { my($self, $other, $swap) = @_;
539 1161         2149 return ("$self" eq $other);
540             },
541 0     0   0 "cmp" => sub { my($self, $other, $swap) = @_;
542 0 0       0 return ($swap ? $other cmp "$self" : "$self" cmp $other);
543             },
544 45 50   45   242 "<=>" => sub { $_[2] ? $_[1]->enum <=> $_[0]->enum :
545             $_[0]->enum <=> $_[1]->enum },
546 125     125   159900 );
  125         157728  
  125         1721  
547              
548              
549             } # package: PDL::Type
550             # Return
551             1;
552              
553             __END__