summaryrefslogtreecommitdiff
path: root/perllib/Graph/Attribute.pm
blob: 54fa29a3bebd305a225dd667bdae0eaf090913d6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package Graph::Attribute;

use strict;

sub _F () { 0 }
sub _COMPAT02 () { 0x00000001 }

sub import {
    my $package = shift;
    my %attr = @_;
    my $caller = caller(0);
    if (exists $attr{array}) {
	my $i = $attr{array};
	no strict 'refs';
	*{"${caller}::_get_attributes"} = sub { $_[0]->[ $i ] };
	*{"${caller}::_set_attributes"} =
	    sub { $_[0]->[ $i ] ||= { };
		  $_[0]->[ $i ] = $_[1] if @_ == 2;
		  $_[0]->[ $i ] };
	*{"${caller}::_has_attributes"} = sub { defined $_[0]->[ $i ] };
	*{"${caller}::_delete_attributes"} = sub { undef $_[0]->[ $i ]; 1 };
    } elsif (exists $attr{hash}) {
	my $k = $attr{hash};
	no strict 'refs';
	*{"${caller}::_get_attributes"} = sub { $_[0]->{ $k } };
	*{"${caller}::_set_attributes"} =
	    sub { $_[0]->{ $k } ||= { };
		  $_[0]->{ $k } = $_[1] if @_ == 2;
		  $_[0]->{ $k } };
	*{"${caller}::_has_attributes"} = sub { defined $_[0]->{ $k } };
	*{"${caller}::_delete_attributes"} = sub { delete $_[0]->{ $k } };
    } else {
	die "Graph::Attribute::import($package @_) caller $caller\n";
    }
    my @api = qw(get_attribute
		 get_attributes
		 set_attribute
		 set_attributes
		 has_attribute
		 has_attributes
		 delete_attribute
		 delete_attributes
		 get_attribute_names
		 get_attribute_values);
    if (exists $attr{map}) {
	my $map = $attr{map};
	for my $api (@api) {
	    my ($first, $rest) = ($api =~ /^(\w+?)_(.+)/);
	    no strict 'refs';
	    *{"${caller}::${first}_${map}_${rest}"} = \&$api;
	}
    }
}

sub set_attribute {
    my $g = shift;
    my $v = pop;
    my $a = pop;
    my $p = $g->_set_attributes;
    $p->{ $a } = $v;
    return 1;
}

sub set_attributes {
    my $g = shift;
    my $a = pop;
    my $p = $g->_set_attributes( $a );
    return 1;
}

sub has_attribute {
    my $g = shift;
    my $a = pop;
    my $p = $g->_get_attributes;
    $p ? exists $p->{ $a } : 0;
}

sub has_attributes {
    my $g = shift;
    $g->_get_attributes ? 1 : 0;
}

sub get_attribute {
    my $g = shift;
    my $a = pop;
    my $p = $g->_get_attributes;
    $p ? $p->{ $a } : undef;
}

sub delete_attribute {
    my $g = shift;
    my $a = pop;
    my $p = $g->_get_attributes;
    if (defined $p) {
	delete $p->{ $a };
	return 1;
    } else {
	return 0;
    }
}

sub delete_attributes {
    my $g = shift;
    if ($g->_has_attributes) {
	$g->_delete_attributes;
	return 1;
    } else {
	return 0;
    }
}

sub get_attribute_names {
    my $g = shift;
    my $p = $g->_get_attributes;
    defined $p ? keys %{ $p } : ( );
}

sub get_attribute_values {
    my $g = shift;
    my $p = $g->_get_attributes;
    defined $p ? values %{ $p } : ( );
}

sub get_attributes {
    my $g = shift;
    my $a = $g->_get_attributes;
    ($g->[ _F ] & _COMPAT02) ? (defined $a ? %{ $a } : ()) : $a;
}

1;