]> www.ginac.de Git - ginac.git/blobdiff - ginac/registrar.cpp
describe ex_is_less and ex_is_equal
[ginac.git] / ginac / registrar.cpp
index 0d73b51a7581b09eacc0056923999365621f093a..7aee59464f4e4851c88811a9a76a5cb615c7b909 100644 (file)
@@ -3,7 +3,7 @@
  *  GiNaC's class registrar (for class basic and all classes derived from it). */
 
 /*
- *  GiNaC Copyright (C) 1999-2001 Johannes Gutenberg University Mainz, Germany
+ *  GiNaC Copyright (C) 1999-2003 Johannes Gutenberg University Mainz, Germany
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
  */
 
 #include <string>
+#include <map>
 #include <stdexcept>
 
 #include "registrar.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 registered_class_info *first_registered_class = NULL;
 
 /** Find registered_class_info strucure by class name. */
-static inline registered_class_info *find_registered_class_info(const std::string &class_name)
+static const registered_class_info *find_registered_class_info(const std::string &class_name)
 {
-       registered_class_info *p = first_registered_class;
-       while (p) {
-               if (class_name == p->name)
-                       return p;
-               p = p->next;
+       // Use a map for faster lookup. The registered_class_info list doesn't
+       // change at run-time, so it's sufficient to construct the map once
+       // on the first trip through this function.
+       typedef std::map<std::string, const registered_class_info *> name_map_type;
+       static name_map_type name_map;
+       static bool name_map_initialized = false;
+
+       if (!name_map_initialized) {
+               // Construct map
+               const registered_class_info *p = first_registered_class;
+               while (p) {
+                       name_map[p->name] = p;
+                       p = p->next;
+               }
+               name_map_initialized = true;
        }
-       throw (std::runtime_error("class '" + class_name + "' not registered"));
+
+       name_map_type::const_iterator it = name_map.find(class_name);
+       if (it == name_map.end())
+               throw (std::runtime_error("class '" + class_name + "' not registered"));
+       else
+               return it->second;
 }
 
 unsigned int find_tinfo_key(const std::string &class_name)
 {
-       registered_class_info *p = find_registered_class_info(class_name);
+       const registered_class_info *p = find_registered_class_info(class_name);
        return p->tinfo_key;
 }
 
 unarch_func find_unarch_func(const std::string &class_name)
 {
-       registered_class_info *p = find_registered_class_info(class_name);
+       const registered_class_info *p = find_registered_class_info(class_name);
        return p->unarchive;
 }
 
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC