00001 // Copyright (C) 2001 Petter Urkedal (petter.urkedal@matfys.lth.se) 00002 00003 // This file is free software; you can redistribute it and/or modify 00004 // it under the terms of the GNU General Public License as published by 00005 // the Free Software Foundation; either version 2 of the License, or 00006 // (at your option) any later version. 00007 00008 // This file is distributed in the hope that it will be useful, 00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 // GNU General Public License for more details. 00012 00013 // You should have received a copy of the GNU General Public License 00014 // along with this program; if not, write to the Free Software 00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00016 00017 // As a special exception, you may use this file as part of a free 00018 // software library without restriction. Specifically, if other files 00019 // instantiate templates or use macros or inline functions from this 00020 // file, or you compile this file and link it with other files to 00021 // produce an executable, this file does not by itself cause the 00022 // resulting executable to be covered by the GNU General Public 00023 // License. This exception does not however invalidate any other 00024 // reasons why the executable file might be covered by the GNU General 00025 // Public License. 00026 00027 // $Id: hook.h,v 1.1 2002/05/30 18:01:37 petter_urkedal Exp $ 00028 00029 00030 #ifndef MORE_HOOK_H 00031 #define MORE_HOOK_H 00032 00033 #include <vector> 00034 00035 namespace more { 00036 namespace gen { 00037 00038 template<typename Generator = void (*)(void)> 00039 struct hook { 00040 typedef Generator function_type; 00041 00042 // Use vector to optimize for running and for LIFO insert/erase. 00043 typedef std::vector<function_type> container; 00044 00045 int n_gc_mark_hook; 00046 void run() { 00047 for (typename container::iterator it = vect.begin(); 00048 it != vect.end(); ++it) 00049 (**it)(); 00050 } 00051 void insert(function_type f) { vect.push_back(f); } 00052 void erase(function_type f) { 00053 // optimize for LIFO, 00054 typename container::reverse_iterator 00055 it = find(vect.rbegin(), vect.rend(), f); 00056 if (it == vect.rend()) return; 00057 vect.erase(vect.end() - ((it - vect.rbegin()) + 1)); 00058 } 00059 private: 00060 container vect; 00061 }; 00062 00063 }} // more::gen 00064 00065 #endif