1 | // ============================================================= // |
---|
2 | // // |
---|
3 | // File : Group.hxx // |
---|
4 | // Purpose : Handles for taxonomic groups // |
---|
5 | // // |
---|
6 | // Coded by Ralf Westram (coder@reallysoft.de) in March 2017 // |
---|
7 | // http://www.arb-home.de/ // |
---|
8 | // // |
---|
9 | // ============================================================= // |
---|
10 | |
---|
11 | #ifndef GROUP_HXX |
---|
12 | #define GROUP_HXX |
---|
13 | |
---|
14 | #ifndef AP_TREE_HXX |
---|
15 | #include <AP_Tree.hxx> |
---|
16 | #endif |
---|
17 | |
---|
18 | #define td_assert(cond) arb_assert(cond) |
---|
19 | |
---|
20 | class Group { |
---|
21 | RefPtr<GBDATA> gb_group; // NULp = disappeared/invalid group; otherwise points to "/tree_data/tree_XXXX/node" |
---|
22 | mutable RefPtr<AP_tree> node; // NULp = unknown or not searched yet or tree not loaded; otherwise points to corresponding node in loaded tree |
---|
23 | |
---|
24 | public: |
---|
25 | Group() : gb_group(NULp), node(NULp) {} |
---|
26 | Group(GBDATA *gb_group_) : |
---|
27 | gb_group(gb_group_), |
---|
28 | node(NULp) |
---|
29 | { |
---|
30 | td_assert(gb_group_); |
---|
31 | } |
---|
32 | |
---|
33 | Group(AP_tree *node_) : |
---|
34 | gb_group(NULp), |
---|
35 | node(node_) |
---|
36 | { |
---|
37 | if (node->is_normal_group()) { |
---|
38 | gb_group = node->gb_node; |
---|
39 | } |
---|
40 | else { // only point to keeled group if no "normal" group is at node |
---|
41 | td_assert(node->is_keeled_group()); |
---|
42 | gb_group = node->get_father()->gb_node; |
---|
43 | } |
---|
44 | |
---|
45 | td_assert(at_node(node)); |
---|
46 | } |
---|
47 | |
---|
48 | bool is_valid() const { return gb_group; } |
---|
49 | bool is_located() const { |
---|
50 | td_assert(is_valid()); |
---|
51 | return node; |
---|
52 | } |
---|
53 | |
---|
54 | AP_tree *get_node() const { return node; } |
---|
55 | GBDATA *get_group_data() const { return gb_group; } // returns NULp when !is_valid() |
---|
56 | const char *get_name() const { |
---|
57 | td_assert(is_valid()); |
---|
58 | GBDATA *gb_name = GB_entry(gb_group, "group_name"); |
---|
59 | td_assert(gb_name); |
---|
60 | return GB_read_char_pntr(gb_name); |
---|
61 | } |
---|
62 | |
---|
63 | bool locate(AP_tree *subtree) const; |
---|
64 | void dislocate() const { node = NULp; } |
---|
65 | |
---|
66 | bool at_node(AP_tree *test) const { |
---|
67 | if (!gb_group) return false; |
---|
68 | |
---|
69 | bool at = (test->gb_node == gb_group) && test->is_normal_group(); |
---|
70 | if (!at) { // check for group at father keeled down to 'test' |
---|
71 | AP_tree *parent = test->get_father(); |
---|
72 | at = (parent->gb_node == gb_group) && parent->keelsDownGroup(test); |
---|
73 | } |
---|
74 | if (at) { |
---|
75 | if (!node) node = test; // locate on-the-fly |
---|
76 | #if defined(ASSERTION_USED) |
---|
77 | else td_assert(node == test); // detected mislocation |
---|
78 | #endif |
---|
79 | } |
---|
80 | |
---|
81 | return at; |
---|
82 | } |
---|
83 | |
---|
84 | bool operator == (const Group& other) const { return gb_group == other.gb_group; } |
---|
85 | bool operator != (const Group& other) const { return !operator == (other); } |
---|
86 | }; |
---|
87 | |
---|
88 | |
---|
89 | #else |
---|
90 | #error Group.hxx included twice |
---|
91 | #endif // GROUP_HXX |
---|