00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef SYMNODE_H_
00019 #define SYMNODE_H_
00020
00021 #include <cassert>
00022
00023 #if __GNUC__ >= 3
00024 #include <backward/hash_map.h>
00025 #elif __GNUC__ < 3
00026 #include <hash_map.h>
00027 using std::hash_map;
00028 #endif
00029
00030
00031 struct UniqueNodeStats { virtual ~UniqueNodeStats(){} };
00032
00033 #include "SymImpl.h"
00034 #include "token.h"
00035
00036 #if __GNUC__ == 4
00037 #define USE_TR1 1
00038 #else
00039 #define USE_TR1 0
00040 #endif
00041
00042 #if USE_TR1
00043 #include <tr1/unordered_map>
00044 typedef std::tr1::unordered_map<detail::SymKey, detail::SymValue, detail::SymKey::Hash> SymMap;
00045 #else
00046 typedef hash_map<detail::SymKey, detail::SymValue, detail::SymKey::Hash> SymMap;
00047 #endif
00048
00049 typedef SymMap::iterator SymIterator;
00050
00051
00052
00053 class Sym
00054 {
00055 public:
00056
00057 Sym() : node(dag.end()) {}
00058 explicit Sym(token_t token, const SymVec& args);
00059 explicit Sym(token_t token, const Sym& args);
00060 explicit Sym(token_t var);
00061
00062 explicit Sym(SymIterator it) : node(it) { incref(); }
00063
00064 Sym(const Sym& oth) : node(oth.node) { incref(); }
00065 ~Sym() { decref(); }
00066
00067 const Sym& operator=(const Sym& oth) {
00068 if (oth.node == node) return *this;
00069 decref();
00070 node = oth.node;
00071 incref();
00072 return *this;
00073 }
00074
00075
00076 UniqueNodeStats* extra_stats() const { return empty()? 0 : node->second.uniqueNodeStats; }
00077
00078 int hashcode() const { return node->first.get_hash_code(); }
00079
00080
00081 friend struct detail::SymKey::Hash;
00082 friend struct detail::SymKey;
00083
00084 unsigned refcount() const { return empty()? 0: node->second.refcount; }
00085
00086 bool operator==(const Sym& other) const {
00087 return node == other.node;
00088 }
00089 bool operator!=(const Sym& other) const { return !(*this == other); }
00090
00091 bool empty() const { return node == dag.end(); }
00092
00093
00094 unsigned arity() const { return node->first.arity(); }
00095 token_t token() const { return node->first.token; }
00096
00097 const SymVec& args() const { return node->first.vec(); }
00098
00099
00100 unsigned size() const { return empty()? 0 : node->second.size; }
00101 unsigned depth() const { return empty()? 0 : node->second.depth; }
00102
00103 SymMap::iterator iterator() const { return node; }
00104
00105
00106 static SymMap& get_dag() { return dag; }
00107
00108
00109
00110 static void set_factory_function(UniqueNodeStats* (*f)(const Sym&)) { factory=f; }
00111 static void clear_factory_function() { factory = 0; }
00112
00113 static const std::vector<unsigned>& token_refcount() { return token_count; }
00114
00115 unsigned address() const { return reinterpret_cast<unsigned>(&*node); }
00116
00117 private :
00118
00119
00120 Sym private_get(size_t w) const;
00121
00122 unsigned __unchecked_refcount() const { return node->second.refcount; }
00123
00124 void incref() {
00125 if (!empty()) {
00126 ++(node->second.refcount);
00127 ++token_count[token()];
00128 }
00129 }
00130 void decref() {
00131 if (!empty()) {
00132 --token_count[token()];
00133 if (--(node->second.refcount) == 0) {
00134 dag.erase(node);
00135 }
00136 }
00137 }
00138
00139
00140 SymIterator node;
00141
00142
00143 static SymMap dag;
00144
00145 static std::vector<unsigned> token_count;
00146
00147
00148 static UniqueNodeStats* (*factory)(const Sym&);
00149
00150 };
00151
00152
00153 class HashSym {
00154 public:
00155 int operator()(const Sym& sym) const { return sym.hashcode(); }
00156 };
00157
00158
00159
00160
00161 Sym get_subtree(const Sym& org, size_t w);
00162
00163
00164 Sym insert_subtree(const Sym& org, size_t w, const Sym& nw);
00165
00166
00167 inline Sym next(const Sym& sym) {
00168 SymIterator it = sym.iterator();
00169 ++it;
00170 if (it == Sym::get_dag().end()) it = Sym::get_dag().begin();
00171 return Sym(it);
00172 }
00173
00174 #endif