Merge branch 'dev' of feistymeow.org:feisty_meow into dev
[feisty_meow.git] / nucleus / library / nodes / node.cpp
1 /*****************************************************************************\
2 *                                                                             *
3 *  Name   : node                                                              *
4 *  Author : Chris Koeritz                                                     *
5 *                                                                             *
6 *******************************************************************************
7 * Copyright (c) 1992-$now By Author.  This program is free software; you can  *
8 * redistribute it and/or modify it under the terms of the GNU General Public  *
9 * License as published by the Free Software Foundation; either version 2 of   *
10 * the License or (at your option) any later version.  This is online at:      *
11 *     http://www.fsf.org/copyleft/gpl.html                                    *
12 * Please send any updates to: fred@gruntose.com                               *
13 \*****************************************************************************/
14
15 #include "node.h"
16
17 #include <basis/functions.h>
18 #include <basis/guards.h>
19 #include <structures/amorph.h>
20
21 using namespace basis;
22 using namespace structures;
23
24 namespace nodes {
25
26 // the internal_link class anonymously hangs onto a pointer to the object.
27 struct internal_link {
28   node *_connection;
29   internal_link(node *destination = NULL_POINTER) : _connection(destination) {}
30   virtual ~internal_link() { _connection = NULL_POINTER; }
31 };
32
33 class node_link_amorph : public amorph<internal_link>
34 {
35 public:
36   node_link_amorph(int num) : amorph<internal_link>(num) {}
37 };
38
39 //////////////
40
41 node::node(int number_of_links)
42 : _links(new node_link_amorph(number_of_links))
43 { for (int i = 0; i < number_of_links; i++) set_empty(i); }
44
45 node::~node()
46 {
47   _links->reset();
48   WHACK(_links);
49 }
50
51 int node::links() const { return _links->elements(); }
52
53 // set_empty: assumes used correctly by internal functions--no bounds return.
54 void node::set_empty(int link_num)
55 {
56   internal_link *blank_frank = new internal_link(NULL_POINTER);
57   _links->put(link_num, blank_frank);
58 }
59
60 #define test_arg(link_num) bounds_return(link_num, 0, _links->elements()-1, );
61
62 void node::set_link(int link_number, node *new_link)
63 {
64   test_arg(link_number);
65   (*_links)[link_number]->_connection = new_link;
66 }
67
68 void node::zap_link(int link_number)
69 {
70   test_arg(link_number);
71   _links->zap(link_number, link_number);
72 }
73
74 void node::insert_link(int where, node *to_insert)
75 {
76   // make sure that the index to insert at will not be rejected by the
77   // amorph insert operation.
78   if (where > links())
79     where = links();
80   _links->insert(where, 1);
81   set_empty(where);
82   set_link(where, to_insert);
83 }
84
85 node *node::get_link(int link_number) const
86 {
87   bounds_return(link_number, 0, _links->elements()-1, NULL_POINTER);
88   return (*_links)[link_number]->_connection;
89 }
90
91 int node::which(node *branch_to_find) const
92 {
93   int to_return = common::NOT_FOUND;
94   for (int i = 0; i <= links() - 1; i++)
95     if (branch_to_find == get_link(i)) {
96       to_return = i;
97       break;
98     }
99   return to_return;
100 }
101
102 } // namespace.
103