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