Added mathsym+tcc and boost against all advice
This commit is contained in:
parent
58ae49dd99
commit
90702a435d
136 changed files with 14409 additions and 0 deletions
164
eo/contrib/mathsym/sym/Sym.h
Normal file
164
eo/contrib/mathsym/sym/Sym.h
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
* Copyright (C) 2005 Maarten Keijzer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef SYMNODE_H_
|
||||
#define SYMNODE_H_
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#if __GNUC__ == 3
|
||||
#include <backward/hash_map.h>
|
||||
#else
|
||||
#include <hash_map.h>
|
||||
using std::hash_map;
|
||||
#endif
|
||||
|
||||
/* Empty 'extra statistics' structure, derive from this to keep other characteristics of nodes */
|
||||
struct UniqueNodeStats { virtual ~UniqueNodeStats(){} };
|
||||
|
||||
#include "SymImpl.h"
|
||||
#include "token.h"
|
||||
|
||||
typedef hash_map<detail::SymKey, detail::SymValue, detail::SymKey::Hash> SymMap;
|
||||
typedef SymMap::iterator SymIterator;
|
||||
class Sym;
|
||||
|
||||
typedef std::vector<Sym> SymVec;
|
||||
|
||||
/* Sym is the tree, for which all the nodes are stored in a hash table.
|
||||
* This makes checking for equality O(1) */
|
||||
|
||||
class Sym
|
||||
{
|
||||
public:
|
||||
|
||||
Sym() : node(dag.end()) {}
|
||||
explicit Sym(token_t token, const SymVec& args);
|
||||
explicit Sym(token_t token, const Sym& args);
|
||||
explicit Sym(token_t var);
|
||||
|
||||
explicit Sym(SymIterator it) : node(it) { incref(); }
|
||||
|
||||
Sym(const Sym& oth) : node(oth.node) { incref(); }
|
||||
~Sym() { decref(); }
|
||||
|
||||
const Sym& operator=(const Sym& oth) {
|
||||
if (oth.node == node) return *this;
|
||||
decref();
|
||||
node = oth.node;
|
||||
incref();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* Unique Stats are user defined */
|
||||
UniqueNodeStats* extra_stats() const { return empty()? 0 : node->second.uniqueNodeStats; }
|
||||
|
||||
int hashcode() const { detail::SymKey::Hash hash; return hash(node->first); }
|
||||
|
||||
// Friends, need to touch the node
|
||||
friend struct detail::SymKey::Hash;
|
||||
friend struct detail::SymKey;
|
||||
|
||||
unsigned refcount() const { return empty()? 0: node->second.refcount; }
|
||||
|
||||
bool operator==(const Sym& other) const {
|
||||
return node == other.node;
|
||||
}
|
||||
bool operator!=(const Sym& other) const { return !(*this == other); }
|
||||
|
||||
bool empty() const { return node == dag.end(); }
|
||||
|
||||
/* Support for traversing trees */
|
||||
unsigned arity() const { return node->first.arity(); }
|
||||
token_t token() const { assert(!empty()); return node->first.token; }
|
||||
|
||||
const SymVec& args() const { return node->first.vec(); }
|
||||
|
||||
/* size() - depth */
|
||||
unsigned size() const { return empty()? 0 : node->second.size; }
|
||||
unsigned depth() const { return empty()? 0 : node->second.depth; }
|
||||
|
||||
SymMap::iterator iterator() const { return node; }
|
||||
|
||||
/* Statics accessing some static members */
|
||||
static SymMap& get_dag() { return dag; }
|
||||
|
||||
/* This function can be set to create some UniqueNodeStats derivative that can contain extra stats for a node,
|
||||
* it can for instance be used to create ERC's and what not. */
|
||||
static void set_factory_function(UniqueNodeStats* (*f)(const Sym&)) { factory=f; }
|
||||
static void clear_factory_function() { factory = 0; }
|
||||
|
||||
static void set_extra_dtor( void (*extra)(token_t) ) { extra_dtor = extra; }
|
||||
|
||||
unsigned address() const { return reinterpret_cast<unsigned>(&*node); }
|
||||
|
||||
private :
|
||||
|
||||
// implements getting subtrees
|
||||
Sym private_get(size_t w) const;
|
||||
|
||||
unsigned __unchecked_refcount() const { return node->second.refcount; }
|
||||
|
||||
void incref() {
|
||||
if (!empty())
|
||||
++(node->second.refcount);
|
||||
}
|
||||
void decref() {
|
||||
if (!empty() && --(node->second.refcount) == 0) {
|
||||
if (extra_dtor) {
|
||||
extra_dtor(token());
|
||||
}
|
||||
dag.erase(node);
|
||||
}
|
||||
}
|
||||
|
||||
// The one and only data member, an iterator into the static map below
|
||||
SymIterator node;
|
||||
|
||||
// A static hash_map that contains all live nodes..
|
||||
static SymMap dag;
|
||||
|
||||
// Factory function for creating extra node stats, default will be 0
|
||||
static UniqueNodeStats* (*factory)(const Sym&);
|
||||
|
||||
static void (*extra_dtor)(token_t);
|
||||
|
||||
};
|
||||
|
||||
/* Utility hash functor for syms */
|
||||
class HashSym {
|
||||
public:
|
||||
int operator()(const Sym& sym) const { return sym.hashcode(); }
|
||||
};
|
||||
|
||||
/* Utility Functions */
|
||||
|
||||
// get_subtree retrieves a subtree by standard ordering (0=root, and then depth first)
|
||||
Sym get_subtree(const Sym& org, size_t w);
|
||||
|
||||
// insert_subtree uses the same ordering as get and inserts the second argument, returning a new tree
|
||||
Sym insert_subtree(const Sym& org, size_t w, const Sym& nw);
|
||||
|
||||
/* Get the successor from the hashtable, no particular purpose other than an interesting way to mutate */
|
||||
inline Sym next(const Sym& sym) {
|
||||
SymIterator it = sym.iterator();
|
||||
++it;
|
||||
if (it == Sym::get_dag().end()) it = Sym::get_dag().begin();
|
||||
return Sym(it);
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in a new issue