| 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 |
|---|