From cb7f385d431299b286485dd1ca46621353184e0d Mon Sep 17 00:00:00 2001
From: sjplimp <sjplimp@f3b2605a-c512-4ea7-a41b-209d697bcdaa>
Date: Tue, 23 Jul 2013 19:01:37 +0000
Subject: [PATCH] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@10310
 f3b2605a-c512-4ea7-a41b-209d697bcdaa

---
 src/Make.sh         |   2 +-
 src/force.cpp       |  49 ++++++----
 src/force.h         |   8 ++
 src/input.cpp       | 216 ++++++++++++++++++++++++--------------------
 src/input.h         |   7 ++
 src/modify.cpp      | 117 +++++++++++++-----------
 src/modify.h        |  12 +++
 src/pair_hybrid.cpp |  53 +----------
 src/pair_hybrid.h   |   5 -
 9 files changed, 244 insertions(+), 225 deletions(-)

diff --git a/src/Make.sh b/src/Make.sh
index 3b8ef4c130..3362c03233 100644
--- a/src/Make.sh
+++ b/src/Make.sh
@@ -71,7 +71,7 @@ if (test $1 = "style") then
   style INTEGRATE_CLASS ""          integrate  update
   style KSPACE_CLASS    ""          kspace     force
   style MINIMIZE_CLASS  min_        minimize   update
-  style PAIR_CLASS      pair_       pair       force      pair_hybrid
+  style PAIR_CLASS      pair_       pair       force
   style READER_CLASS    reader_     reader     read_dump
   style REGION_CLASS    region_     region     domain
 
diff --git a/src/force.cpp b/src/force.cpp
index 096f4ef753..eceed4297a 100644
--- a/src/force.cpp
+++ b/src/force.cpp
@@ -73,6 +73,17 @@ Force::Force(LAMMPS *lmp) : Pointers(lmp)
   strcpy(improper_style,str);
   kspace_style = new char[n];
   strcpy(kspace_style,str);
+
+  // fill pair map with fixes listed in style_pair.h
+
+  pair_map = new std::map<std::string,PairCreator>();
+
+#define PAIR_CLASS
+#define PairStyle(key,Class) \
+  (*pair_map)[#key] = &pair_creator<Class>;
+#include "style_pair.h"
+#undef PairStyle
+#undef PAIR_CLASS
 }
 
 /* ---------------------------------------------------------------------- */
@@ -134,7 +145,8 @@ void Force::create_pair(const char *style, const char *suffix)
 }
 
 /* ----------------------------------------------------------------------
-   generate a pair class, first with suffix appended
+   generate a pair class
+   try first with suffix appended
 ------------------------------------------------------------------------- */
 
 Pair *Force::new_pair(const char *style, const char *suffix, int &sflag)
@@ -144,31 +156,34 @@ Pair *Force::new_pair(const char *style, const char *suffix, int &sflag)
     char estyle[256];
     sprintf(estyle,"%s/%s",style,suffix);
 
-    if (0) return NULL;
-
-#define PAIR_CLASS
-#define PairStyle(key,Class) \
-    else if (strcmp(estyle,#key) == 0) return new Class(lmp);
-#include "style_pair.h"
-#undef PairStyle
-#undef PAIR_CLASS
-
+    if (pair_map->find(estyle) != pair_map->end()) {
+      PairCreator pair_creator = (*pair_map)[estyle];
+      return pair_creator(lmp);
+    }
   }
 
   sflag = 0;
 
   if (strcmp(style,"none") == 0) return NULL;
+  if (pair_map->find(style) != pair_map->end()) {
+    PairCreator pair_creator = (*pair_map)[style];
+    return pair_creator(lmp);
+  }
 
-#define PAIR_CLASS
-#define PairStyle(key,Class) \
-  else if (strcmp(style,#key) == 0) return new Class(lmp);
-#include "style_pair.h"
-#undef PAIR_CLASS
-
-  else error->all(FLERR,"Invalid pair style");
+  error->all(FLERR,"Invalid pair style");
   return NULL;
 }
 
+/* ----------------------------------------------------------------------
+   one instance per pair style in style_pair.h
+------------------------------------------------------------------------- */
+
+template <typename T>
+Pair *Force::pair_creator(LAMMPS *lmp)
+{
+  return new T(lmp);
+}
+
 /* ----------------------------------------------------------------------
    return ptr to Pair class if matches word or matches hybrid sub-style
    if exact, then style name must be exact match to word
diff --git a/src/force.h b/src/force.h
index 1c9b352567..b7ba7f63c2 100644
--- a/src/force.h
+++ b/src/force.h
@@ -15,6 +15,8 @@
 #define LMP_FORCE_H
 
 #include "pointers.h"
+#include <map>
+#include <string>
 
 namespace LAMMPS_NS {
 
@@ -45,6 +47,9 @@ class Force : protected Pointers {
   class Pair *pair;
   char *pair_style;
 
+  typedef Pair *(*PairCreator)(LAMMPS *);
+  std::map<std::string,PairCreator> *pair_map;
+
   class Bond *bond;
   char *bond_style;
 
@@ -98,6 +103,9 @@ class Force : protected Pointers {
   double numeric(const char *, int, char *);
   int inumeric(const char *, int, char *);
   bigint memory_usage();
+
+ private:
+  template <typename T> static Pair *pair_creator(LAMMPS *);
 };
 
 }
diff --git a/src/input.cpp b/src/input.cpp
index 578fe17888..67e72db959 100644
--- a/src/input.cpp
+++ b/src/input.cpp
@@ -82,6 +82,17 @@ Input::Input(LAMMPS *lmp, int argc, char **argv) : Pointers(lmp)
 
   variable = new Variable(lmp);
 
+  // fill map with commands listed in style_command.h
+
+  command_map = new std::map<std::string,CommandCreator>();
+
+#define COMMAND_CLASS
+#define CommandStyle(key,Class) \
+  (*command_map)[#key] = &command_creator<Class>;
+#include "style_command.h"
+#undef CommandStyle
+#undef COMMAND_CLASS
+
   // process command-line args
   // check for args "-var" and "-echo"
   // caller has already checked that sufficient arguments exist
@@ -101,7 +112,7 @@ Input::Input(LAMMPS *lmp, int argc, char **argv) : Pointers(lmp)
       echo();
       arg = tmp;
       iarg += 2;
-    } else iarg++;
+     } else iarg++;
   }
 }
 
@@ -129,13 +140,13 @@ Input::~Input()
 void Input::file()
 {
   int m,n;
-
+  
   while (1) {
-
+    
     // read a line from input script
     // n = length of line including str terminator, 0 if end of file
     // if line ends in continuation char '&', concatenate next line
-
+    
     if (me == 0) {
       m = 0;
       while (1) {
@@ -147,7 +158,7 @@ void Input::file()
         }
         m = strlen(line);
         if (line[m-1] != '\n') continue;
-
+        
         m--;
         while (m >= 0 && isspace(line[m])) m--;
         if (m < 0 || line[m] != '&') {
@@ -157,13 +168,13 @@ void Input::file()
         }
       }
     }
-
+    
     // bcast the line
     // if n = 0, end-of-file
     // error if label_active is set, since label wasn't encountered
     // if original input file, code is done
     // else go back to previous input file
-
+    
     MPI_Bcast(&n,1,MPI_INT,0,world);
     if (n == 0) {
       if (label_active) error->all(FLERR,"Label wasn't found in input script");
@@ -176,29 +187,29 @@ void Input::file()
       if (me == 0) infile = infiles[nfile-1];
       continue;
     }
-
+    
     if (n > maxline) reallocate(line,maxline,n);
     MPI_Bcast(line,n,MPI_CHAR,0,world);
-
+    
     // echo the command unless scanning for label
-
+    
     if (me == 0 && label_active == 0) {
       if (echo_screen && screen) fprintf(screen,"%s\n",line);
       if (echo_log && logfile) fprintf(logfile,"%s\n",line);
     }
-
+    
     // parse the line
     // if no command, skip to next line in input script
-
+    
     parse();
     if (command == NULL) continue;
-
+    
     // if scanning for label, skip command unless it's a label command
-
+    
     if (label_active && strcmp(command,"label") != 0) continue;
-
+    
     // execute the command
-
+    
     if (execute_command()) {
       char *str = new char[maxline+32];
       sprintf(str,"Unknown command: %s",line);
@@ -210,18 +221,18 @@ void Input::file()
 /* ----------------------------------------------------------------------
    process all input from filename
    called from library interface
-------------------------------------------------------------------------- */
+   ------------------------------------------------------------------------- */
 
 void Input::file(const char *filename)
 {
   // error if another nested file still open, should not be possible
   // open new filename and set infile, infiles[0], nfile
   // call to file() will close filename and decrement nfile
-
+  
   if (me == 0) {
     if (nfile > 1)
       error->one(FLERR,"Invalid use of library file() function");
-
+    
     infile = fopen(filename,"r");
     if (infile == NULL) {
       char str[128];
@@ -231,46 +242,46 @@ void Input::file(const char *filename)
     infiles[0] = infile;
     nfile = 1;
   }
-
+  
   file();
 }
 
 /* ----------------------------------------------------------------------
    copy command in single to line, parse and execute it
    return command name to caller
-------------------------------------------------------------------------- */
+   ------------------------------------------------------------------------- */
 
 char *Input::one(const char *single)
 {
   int n = strlen(single) + 1;
   if (n > maxline) reallocate(line,maxline,n);
   strcpy(line,single);
-
+  
   // echo the command unless scanning for label
-
+  
   if (me == 0 && label_active == 0) {
     if (echo_screen && screen) fprintf(screen,"%s\n",line);
     if (echo_log && logfile) fprintf(logfile,"%s\n",line);
   }
-
+  
   // parse the line
   // if no command, just return NULL
-
+  
   parse();
   if (command == NULL) return NULL;
-
+  
   // if scanning for label, skip command unless it's a label command
-
+  
   if (label_active && strcmp(command,"label") != 0) return NULL;
-
+  
   // execute the command and return its name
-
+  
   if (execute_command()) {
     char *str = new char[maxline+32];
     sprintf(str,"Unknown command: %s",line);
     error->all(FLERR,str);
   }
-
+  
   return command;
 }
 
@@ -282,19 +293,19 @@ char *Input::one(const char *single)
    narg = # of args
    arg[] = individual args
    treat text between single/double quotes as one arg
-------------------------------------------------------------------------- */
+   ------------------------------------------------------------------------- */
 
 void Input::parse()
 {
   // duplicate line into copy string to break into words
-
+  
   int n = strlen(line) + 1;
   if (n > maxcopy) reallocate(copy,maxcopy,n);
   strcpy(copy,line);
-
+  
   // strip any # comment by replacing it with 0
   // do not strip # inside single/double quotes
-
+  
   char quote = '\0';
   char *ptr = copy;
   while (*ptr) {
@@ -306,22 +317,22 @@ void Input::parse()
     else if (*ptr == '"' || *ptr == '\'') quote = *ptr;
     ptr++;
   }
-
+  
   // perform $ variable substitution (print changes)
   // except if searching for a label since earlier variable may not be defined
-
+  
   if (!label_active) substitute(copy,work,maxcopy,maxwork,1);
-
+  
   // command = 1st arg in copy string
-
+  
   char *next;
   command = nextword(copy,&next);
   if (command == NULL) return;
-
+  
   // point arg[] at each subsequent arg in copy string
   // nextword() inserts string terminators into copy string to delimit args
   // nextword() treats text between single/double quotes as one arg
-
+  
   narg = 0;
   ptr = next;
   while (ptr) {
@@ -341,20 +352,20 @@ void Input::parse()
    insert 0 at end of word
    ignore leading whitespace
    treat text between single/double quotes as one arg
-     matching quote must be followed by whitespace char if not end of string
-     strip quotes from returned word
+   matching quote must be followed by whitespace char if not end of string
+   strip quotes from returned word
    return ptr to start of word
    return next = ptr after word or NULL if word ended with 0
    return NULL if no word in string
-------------------------------------------------------------------------- */
+   ------------------------------------------------------------------------- */
 
 char *Input::nextword(char *str, char **next)
 {
   char *start,*stop;
-
+  
   start = &str[strspn(str," \t\n\v\f\r")];
   if (*start == '\0') return NULL;
-
+  
   if (*start == '"' || *start == '\'') {
     stop = strchr(&start[1],*start);
     if (!stop) error->all(FLERR,"Unbalanced quotes in input line");
@@ -362,7 +373,7 @@ char *Input::nextword(char *str, char **next)
       error->all(FLERR,"Input line quote not followed by whitespace");
     start++;
   } else stop = &start[strcspn(start," \t\n\v\f\r")];
-
+  
   if (*stop == '\0') *next = NULL;
   else *next = stop+1;
   *stop = '\0';
@@ -374,7 +385,7 @@ char *Input::nextword(char *str, char **next)
    reallocate str/str2 to hold expanded version if necessary & reset max/max2
    print updated string if flag is set and not searching for label
    label_active will be 0 if called from external class
-------------------------------------------------------------------------- */
+   ------------------------------------------------------------------------- */
 
 void Input::substitute(char *&str, char *&str2, int &max, int &max2, int flag)
 {
@@ -385,61 +396,61 @@ void Input::substitute(char *&str, char *&str2, int &max, int &max2, int flag)
   //   if $ is followed by '{', trailing '}' becomes NULL
   //   else $x becomes x followed by NULL
   // beyond = points to text following variable
-
+  
   int i,n,paren_count;
   char immediate[256];
   char *var,*value,*beyond;
   char quote = '\0';
   char *ptr = str;
-
+  
   n = strlen(str) + 1;
   if (n > max2) reallocate(str2,max2,n);
   *str2 = '\0';
   char *ptr2 = str2;
-
+  
   while (*ptr) {
     // variable substitution
-
+    
     if (*ptr == '$' && !quote) {
-
+      
       // value = ptr to expanded variable
       // variable name between curly braces, e.g. ${a}
-
+      
       if (*(ptr+1) == '{') {
         var = ptr+2;
         i = 0;
-
+        
         while (var[i] != '\0' && var[i] != '}') i++;
-
+        
         if (var[i] == '\0') error->one(FLERR,"Invalid variable name");
         var[i] = '\0';
         beyond = ptr + strlen(var) + 3;
         value = variable->retrieve(var);
-
-      // immediate variable between parenthesis, e.g. $(1/2)
-
+        
+        // immediate variable between parenthesis, e.g. $(1/2)
+        
       } else if (*(ptr+1) == '(') {
         var = ptr+2;
         paren_count = 0;
         i = 0;
-
+        
         while (var[i] != '\0' && !(var[i] == ')' && paren_count == 0)) {
           switch (var[i]) {
-            case '(': paren_count++; break;
-            case ')': paren_count--; break;
-            default: ;
+          case '(': paren_count++; break;
+          case ')': paren_count--; break;
+          default: ;
           }
           i++;
         }
-
+        
         if (var[i] == '\0') error->one(FLERR,"Invalid immediate variable");
         var[i] = '\0';
         beyond = ptr + strlen(var) + 3;
         sprintf(immediate,"%.20g",variable->compute_equal(var));
         value = immediate;
-
-      // single character variable name, e.g. $a
-
+        
+        // single character variable name, e.g. $a
+        
       } else {
         var = ptr;
         var[0] = var[1];
@@ -447,40 +458,40 @@ void Input::substitute(char *&str, char *&str2, int &max, int &max2, int flag)
         beyond = ptr + 2;
         value = variable->retrieve(var);
       }
-
+      
       if (value == NULL) error->one(FLERR,"Substitution for illegal variable");
-
+      
       // check if storage in str2 needs to be expanded
       // re-initialize ptr and ptr2 to the point beyond the variable.
-
+      
       n = strlen(str2) + strlen(value) + strlen(beyond) + 1;
       if (n > max2) reallocate(str2,max2,n);
       strcat(str2,value);
       ptr2 = str2 + strlen(str2);
       ptr = beyond;
-
+      
       // output substitution progress if requested
-
+      
       if (flag && me == 0 && label_active == 0) {
         if (echo_screen && screen) fprintf(screen,"%s%s\n",str2,beyond);
         if (echo_log && logfile) fprintf(logfile,"%s%s\n",str2,beyond);
       }
-
+      
       continue;
     }
-
+    
     if (*ptr == quote) quote = '\0';
     else if (*ptr == '"' || *ptr == '\'') quote = *ptr;
-
+    
     // copy current character into str2
-
+    
     *ptr2++ = *ptr++;
     *ptr2 = '\0';
   }
-
+  
   // set length of input str to length of work str2
   // copy work string back to input str
-
+  
   if (max2 > max) reallocate(str,max,max2);
   strcpy(str,str2);
 }
@@ -489,26 +500,26 @@ void Input::substitute(char *&str, char *&str2, int &max, int &max2, int flag)
    rellocate a string
    if n > 0: set max >= n in increments of DELTALINE
    if n = 0: just increment max by DELTALINE
-------------------------------------------------------------------------- */
+   ------------------------------------------------------------------------- */
 
 void Input::reallocate(char *&str, int &max, int n)
 {
   if (n) {
     while (n > max) max += DELTALINE;
   } else max += DELTALINE;
-
+  
   str = (char *) memory->srealloc(str,max*sizeof(char),"input:str");
 }
 
 /* ----------------------------------------------------------------------
    process a single parsed command
    return 0 if successful, -1 if did not recognize command
-------------------------------------------------------------------------- */
+   ------------------------------------------------------------------------- */
 
 int Input::execute_command()
 {
   int flag = 1;
-
+  
   if (!strcmp(command,"clear")) clear();
   else if (!strcmp(command,"echo")) echo();
   else if (!strcmp(command,"if")) ifthenelse();
@@ -522,7 +533,7 @@ int Input::execute_command()
   else if (!strcmp(command,"quit")) quit();
   else if (!strcmp(command,"shell")) shell();
   else if (!strcmp(command,"variable")) variable_command();
-
+  
   else if (!strcmp(command,"angle_coeff")) angle_coeff();
   else if (!strcmp(command,"angle_style")) angle_style();
   else if (!strcmp(command,"atom_modify")) atom_modify();
@@ -574,32 +585,37 @@ int Input::execute_command()
   else if (!strcmp(command,"undump")) undump();
   else if (!strcmp(command,"unfix")) unfix();
   else if (!strcmp(command,"units")) units();
-
+  
   else flag = 0;
-
+  
   // return if command was listed above
-
+  
   if (flag) return 0;
-
-  // check if command is added via style.h
-
-  if (0) return 0;      // dummy line to enable else-if macro expansion
-
-#define COMMAND_CLASS
-#define CommandStyle(key,Class)         \
-  else if (strcmp(command,#key) == 0) { \
-    Class key(lmp);                     \
-    key.command(narg,arg);              \
-    return 0;                           \
+  
+  // invoke commands added via style_command.h
+  
+  if (command_map->find(command) != command_map->end()) {
+    CommandCreator command_creator = (*command_map)[command];
+    command_creator(lmp,narg,arg);
+    return 0;
   }
-#include "style_command.h"
-#undef COMMAND_CLASS
-
+  
   // unrecognized command
-
+  
   return -1;
 }
 
+/* ----------------------------------------------------------------------
+   one instance per command in style_command.h
+------------------------------------------------------------------------- */
+
+template <typename T>
+void Input::command_creator(LAMMPS *lmp, int narg, char **arg)
+{
+  T cmd(lmp);
+  cmd.command(narg,arg);
+}
+
 /* ---------------------------------------------------------------------- */
 /* ---------------------------------------------------------------------- */
 /* ---------------------------------------------------------------------- */
diff --git a/src/input.h b/src/input.h
index b00d5c44ca..d0d3620058 100644
--- a/src/input.h
+++ b/src/input.h
@@ -16,6 +16,8 @@
 
 #include "stdio.h"
 #include "pointers.h"
+#include <map>
+#include <string>
 
 namespace LAMMPS_NS {
 
@@ -49,6 +51,11 @@ class Input : protected Pointers {
 
   FILE **infiles;              // list of open input files
 
+  typedef void (*CommandCreator)(LAMMPS *, int, char **);
+  std::map<std::string,CommandCreator> *command_map;
+
+  template <typename T> static void command_creator(LAMMPS *, int, char **);
+
   void parse();                          // parse an input text line
   char *nextword(char *, char **);       // find next word in string with quotes
   void reallocate(char *&, int &, int);  // reallocate a char string
diff --git a/src/modify.cpp b/src/modify.cpp
index 6a9482fb08..eb5815a7c9 100644
--- a/src/modify.cpp
+++ b/src/modify.cpp
@@ -72,6 +72,28 @@ Modify::Modify(LAMMPS *lmp) : Pointers(lmp)
 
   ncompute = maxcompute = 0;
   compute = NULL;
+
+  // fill map with fixes listed in style_fix.h
+
+  fix_map = new std::map<std::string,FixCreator>();
+
+#define FIX_CLASS
+#define FixStyle(key,Class) \
+  (*fix_map)[#key] = &fix_creator<Class>;
+#include "style_fix.h"
+#undef FixStyle
+#undef FIX_CLASS
+
+  // fill map with computes listed in style_compute.h
+
+  compute_map = new std::map<std::string,ComputeCreator>();
+
+#define COMPUTE_CLASS
+#define ComputeStyle(key,Class) \
+  (*compute_map)[#key] = &compute_creator<Class>;
+#include "style_compute.h"
+#undef ComputeStyle
+#undef COMPUTE_CLASS
 }
 
 /* ---------------------------------------------------------------------- */
@@ -666,40 +688,27 @@ void Modify::add_fix(int narg, char **arg, char *suffix)
     }
   }
 
-  // create the Fix, first with suffix appended
+  // create the Fix
+  // try first with suffix appended
 
-  int success = 0;
+  fix[ifix] = NULL;
 
   if (suffix && lmp->suffix_enable) {
     char estyle[256];
     sprintf(estyle,"%s/%s",arg[2],suffix);
-    success = 1;
-
-    if (0) return;
-
-#define FIX_CLASS
-#define FixStyle(key,Class) \
-    else if (strcmp(estyle,#key) == 0) fix[ifix] = new Class(lmp,narg,arg);
-#include "style_fix.h"
-#undef FixStyle
-#undef FIX_CLASS
-
-    else success = 0;
+    if (fix_map->find(estyle) != fix_map->end()) {
+      FixCreator fix_creator = (*fix_map)[estyle];
+      fix[ifix] = fix_creator(lmp,narg,arg);
+    }
   }
 
-  if (!success) {
-    if (0) return;
-
-#define FIX_CLASS
-#define FixStyle(key,Class) \
-    else if (strcmp(arg[2],#key) == 0) fix[ifix] = new Class(lmp,narg,arg);
-#include "style_fix.h"
-#undef FixStyle
-#undef FIX_CLASS
-
-    else error->all(FLERR,"Invalid fix style");
+  if (fix[ifix] == NULL && fix_map->find(arg[2]) != fix_map->end()) {
+    FixCreator fix_creator = (*fix_map)[arg[2]];
+    fix[ifix] = fix_creator(lmp,narg,arg);
   }
 
+  if (fix[ifix] == NULL) error->all(FLERR,"Invalid fix style");
+
   // set fix mask values and increment nfix (if new)
 
   fmask[ifix] = fix[ifix]->setmask();
@@ -738,6 +747,16 @@ void Modify::add_fix(int narg, char **arg, char *suffix)
     }
 }
 
+/* ----------------------------------------------------------------------
+   one instance per fix in style_fix.h
+------------------------------------------------------------------------- */
+
+template <typename T>
+Fix *Modify::fix_creator(LAMMPS *lmp, int narg, char **arg)
+{
+  return new T(lmp,narg,arg);
+}
+
 /* ----------------------------------------------------------------------
    modify a Fix's parameters
 ------------------------------------------------------------------------- */
@@ -811,43 +830,39 @@ void Modify::add_compute(int narg, char **arg, char *suffix)
       memory->srealloc(compute,maxcompute*sizeof(Compute *),"modify:compute");
   }
 
-  // create the Compute, first with suffix appended
+  // create the Compute
+  // try first with suffix appended
 
-  int success = 0;
+  compute[ncompute] = NULL;
 
   if (suffix && lmp->suffix_enable) {
     char estyle[256];
     sprintf(estyle,"%s/%s",arg[2],suffix);
-    success = 1;
-
-    if (0) return;
-
-#define COMPUTE_CLASS
-#define ComputeStyle(key,Class) \
-    else if (strcmp(estyle,#key) == 0) \
-      compute[ncompute] = new Class(lmp,narg,arg);
-#include "style_compute.h"
-#undef ComputeStyle
-#undef COMPUTE_CLASS
+    if (compute_map->find(estyle) != compute_map->end()) {
+      ComputeCreator compute_creator = (*compute_map)[estyle];
+      compute[ncompute] = compute_creator(lmp,narg,arg);
+    }
+  }
 
-    else success = 0;
+  if (compute[ncompute] == NULL && 
+      compute_map->find(arg[2]) != compute_map->end()) {
+    ComputeCreator compute_creator = (*compute_map)[arg[2]];
+    compute[ncompute] = compute_creator(lmp,narg,arg);
   }
 
-  if (!success) {
-    if (0) return;
+  if (compute[ncompute] == NULL) error->all(FLERR,"Invalid compute style");
 
-#define COMPUTE_CLASS
-#define ComputeStyle(key,Class) \
-    else if (strcmp(arg[2],#key) == 0) \
-      compute[ncompute] = new Class(lmp,narg,arg);
-#include "style_compute.h"
-#undef ComputeStyle
-#undef COMPUTE_CLASS
+  ncompute++;
+}
 
-    else error->all(FLERR,"Invalid compute style");
-  }
+/* ----------------------------------------------------------------------
+   one instance per compute in style_compute.h
+------------------------------------------------------------------------- */
 
-  ncompute++;
+template <typename T>
+Compute *Modify::compute_creator(LAMMPS *lmp, int narg, char **arg)
+{
+  return new T(lmp,narg,arg);
 }
 
 /* ----------------------------------------------------------------------
diff --git a/src/modify.h b/src/modify.h
index c01d8e860a..987026df2d 100644
--- a/src/modify.h
+++ b/src/modify.h
@@ -16,6 +16,8 @@
 
 #include "stdio.h"
 #include "pointers.h"
+#include <map>
+#include <string>
 
 namespace LAMMPS_NS {
 
@@ -135,6 +137,16 @@ class Modify : protected Pointers {
   void list_init_end_of_step(int, int &, int *&);
   void list_init_thermo_energy(int, int &, int *&);
   void list_init_compute();
+
+ private:
+  typedef Compute *(*ComputeCreator)(LAMMPS *, int, char **);
+  std::map<std::string,ComputeCreator> *compute_map;
+
+  typedef Fix *(*FixCreator)(LAMMPS *, int, char **);
+  std::map<std::string,FixCreator> *fix_map;
+
+  template <typename T> static Compute *compute_creator(LAMMPS *, int, char **);
+  template <typename T> static Fix *fix_creator(LAMMPS *, int, char **);
 };
 
 }
diff --git a/src/pair_hybrid.cpp b/src/pair_hybrid.cpp
index 3bba282843..ccf8cda9ba 100644
--- a/src/pair_hybrid.cpp
+++ b/src/pair_hybrid.cpp
@@ -16,7 +16,6 @@
 #include "string.h"
 #include "ctype.h"
 #include "pair_hybrid.h"
-#include "style_pair.h"
 #include "atom.h"
 #include "force.h"
 #include "pair.h"
@@ -211,10 +210,6 @@ void PairHybrid::settings(int narg, char **arg)
   }
   allocated = 0;
 
-  // build list of all known pair styles
-
-  build_styles();
-
   // allocate list of sub-styles as big as possibly needed if no extra args
 
   styles = new Pair*[narg];
@@ -223,7 +218,7 @@ void PairHybrid::settings(int narg, char **arg)
 
   // allocate each sub-style
   // call settings() with set of args that are not pair style names
-  // use known_style() to determine which args these are
+  // use force->pair_map to determine which args these are
 
   int iarg,jarg,dummy;
 
@@ -239,17 +234,12 @@ void PairHybrid::settings(int narg, char **arg)
     keywords[nstyles] = new char[n];
     strcpy(keywords[nstyles],arg[iarg]);
     jarg = iarg + 1;
-    while (jarg < narg && !known_style(arg[jarg])) jarg++;
+    while (jarg < narg && !force->pair_map->count(arg[jarg])) jarg++;
     styles[nstyles]->settings(jarg-iarg-1,&arg[iarg+1]);
     iarg = jarg;
     nstyles++;
   }
 
-  // free allstyles created by build_styles()
-
-  for (int i = 0; i < nallstyles; i++) delete [] allstyles[i];
-  delete [] allstyles;
-
   // multiple[i] = 1 to M if sub-style used multiple times, else 0
 
   for (int i = 0; i < nstyles; i++) {
@@ -762,45 +752,6 @@ int PairHybrid::check_ijtype(int itype, int jtype, char *substyle)
   return 0;
 }
 
-/* ----------------------------------------------------------------------
-   allstyles = list of all pair styles in this LAMMPS executable
-------------------------------------------------------------------------- */
-
-void PairHybrid::build_styles()
-{
-  nallstyles = 0;
-#define PAIR_CLASS
-#define PairStyle(key,Class) nallstyles++;
-#include "style_pair.h"
-#undef PairStyle
-#undef PAIR_CLASS
-
-  allstyles = new char*[nallstyles];
-
-  int n;
-  nallstyles = 0;
-#define PAIR_CLASS
-#define PairStyle(key,Class)                \
-  n = strlen(#key) + 1;                     \
-  allstyles[nallstyles] = new char[n];      \
-  strcpy(allstyles[nallstyles],#key);       \
-  nallstyles++;
-#include "style_pair.h"
-#undef PairStyle
-#undef PAIR_CLASS
-}
-
-/* ----------------------------------------------------------------------
-   allstyles = list of all known pair styles
-------------------------------------------------------------------------- */
-
-int PairHybrid::known_style(char *str)
-{
-  for (int i = 0; i < nallstyles; i++)
-    if (strcmp(str,allstyles[i]) == 0) return 1;
-  return 0;
-}
-
 /* ----------------------------------------------------------------------
    memory usage of each sub-style
 ------------------------------------------------------------------------- */
diff --git a/src/pair_hybrid.h b/src/pair_hybrid.h
index 4f3e61c4a6..f273634ab3 100644
--- a/src/pair_hybrid.h
+++ b/src/pair_hybrid.h
@@ -59,14 +59,9 @@ class PairHybrid : public Pair {
   int **nmap;                   // # of sub-styles itype,jtype points to
   int ***map;                   // list of sub-styles itype,jtype points to
 
-  char **allstyles;
-  int nallstyles;
-
   void allocate();
   void flags();
   virtual void modify_requests();
-  void build_styles();
-  int known_style(char *);
 };
 
 }
-- 
GitLab