diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/config-file.cpp | 240 | ||||
-rw-r--r-- | common/config-file.h | 70 | ||||
-rw-r--r-- | common/config-manager.cpp | 370 | ||||
-rw-r--r-- | common/config-manager.h | 127 | ||||
-rw-r--r-- | common/module.mk | 2 | ||||
-rw-r--r-- | common/singleton.h | 57 |
6 files changed, 555 insertions, 311 deletions
diff --git a/common/config-file.cpp b/common/config-file.cpp deleted file mode 100644 index 4b66e70981..0000000000 --- a/common/config-file.cpp +++ /dev/null @@ -1,240 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2001 Ludvig Strigeus - * Copyright (C) 2001-2003 The ScummVM project - * - * 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 the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * 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. - * - * $Header$ - * - */ - -#include "stdafx.h" -#include "common/config-file.h" -#include "base/engine.h" // for debug() - -#define MAXLINELEN 256 - -static char *ltrim(char *t) { - while (*t == ' ') - t++; - return t; -} - -static char *rtrim(char *t) { - int l = strlen(t) - 1; - while (l >= 0 && t[l] == ' ') - t[l--] = 0; - return t; -} - -// The config-class itself. - -Config::Config (const String &cfg, const String &d) - : filename(cfg), defaultDomain(d), willwrite(false) { - FILE *cfg_file; - char t[MAXLINELEN]; - - if (!(cfg_file = fopen(filename.c_str(), "r"))) { - debug(1, "Unable to open configuration file: %s.\n", filename.c_str()); - } else { - while (!feof(cfg_file)) { - if (!fgets(t, MAXLINELEN, cfg_file)) - continue; - if (t[0] != '#') { - if (t[0] == '[') { - // It's a new domain which begins here. - char *p = strchr(t, ']'); - if (!p) { - debug(1, "Config file buggy: no ] at the end of the domain name.\n"); - } else { - *p = 0; - set_domain(t + 1); - } - } else { - // It's a new key in the domain. - if (defaultDomain.isEmpty()) { - debug(1, "Config file buggy: we have a key without a domain first.\n"); - } - char *p = strchr(t, '\n'); - if (p) - *p = 0; - p = strchr(t, '\r'); - if (p) - *p = 0; - - if (!(p = strchr(t, '='))) { - if (strlen(t)) - debug(1, "Config file buggy: there is junk: %s\n", t); - } else { - char *key, *value; - *p = 0; - key = ltrim(rtrim(t)); - value = ltrim(p + 1); - set(key, value); - } - } - } - } - set_domain(d); - fclose(cfg_file); - } -} - -const char *Config::get(const String &key, const String &d) const { - String domain; - - if (d.isEmpty()) - domain = defaultDomain; - else - domain = d; - - domain.toLowercase(); - if (domains.contains(domain) && domains[domain].contains(key)) - return domains[domain][key].c_str(); - - return 0; -} - -const int Config::getInt(const String &key, int def, const String &d) const { - const char *value = get(key, d); - - if (value) - return atoi(value); - return def; -} - -const bool Config::getBool(const String &key, bool def, const String &d) const { - const char *value = get(key, d); - - if (value) - return !scumm_stricmp(value, "true"); - return def; -} - -void Config::set(const String &key, const String &value, const String &d) { - String domain(d); - - if (domain.isEmpty()) - domain = defaultDomain; - - domain.toLowercase(); - domains[domain][key] = value; -} - -void Config::setInt(const String &key, int value_i, const String &d) { - char value[MAXLINELEN]; - sprintf(value, "%i", value_i); - set(key, String(value), d); -} - -void Config::setBool(const String &key, bool value_b, const String &d) { - String value(value_b ? "true" : "false"); - set(key, value, d); -} - -void Config::set_domain(const String &d) { - defaultDomain = d; - defaultDomain.toLowercase(); -} - -bool Config::has_domain(const String &d) const { - String temp(d); - temp.toLowercase(); - return domains.contains(temp); -} - -void Config::flush() const { - FILE *cfg_file; - - if (!willwrite) - return; - - if (!(cfg_file = fopen(filename.c_str(), "w"))) { - debug(1, "Unable to write configuration file: %s.\n", filename.c_str()); - } else { - DomainMap::ConstIterator d; - for (d = domains.begin(); d != domains.end(); ++d) { - fprintf(cfg_file, "[%s]\n", d->_key.c_str()); - - const StringMap &data = d->_value; - StringMap::ConstIterator x; - for (x = data.begin(); x != data.end(); ++x) { - const String &value = x->_value; - if (!value.isEmpty()) - fprintf(cfg_file, "%s=%s\n", x->_key.c_str(), value.c_str()); - } - fprintf(cfg_file, "\n"); - } - fclose(cfg_file); - } -} - -void Config::rename_domain(const String &oldD, const String &newD) { - String oldDomain(oldD); - String newDomain(newD); - oldDomain.toLowercase(); - newDomain.toLowercase(); - - if (oldDomain == newDomain) - return; - - StringMap &oldHash = domains[oldDomain]; - StringMap &newHash = domains[newDomain]; - - newHash.merge(oldHash); - - domains.remove(oldDomain); -} - -void Config::delete_domain(const String &d) { - String domain(d); - domain.toLowercase(); - domains.remove(d); -} - -void Config::set_filename(const String &f) { - filename = f; -} - -void Config::merge_config(const Config &c) { - DomainMap::ConstIterator d, end(c.domains.end()); - for (d = c.domains.begin(); d != end; ++d) { - domains[d->_key].merge(d->_value); - } -} - -void Config::set_writing(bool w) { - willwrite = w; -} - -const int Config::count_domains() { - int count = 0; - DomainMap::ConstIterator d, end(domains.end()); - for (d = domains.begin(); d != end; ++d) - count++; - - return count; -} - -Common::StringList Config::get_domains() { - StringList domainNames; - DomainMap::ConstIterator d, end(domains.end()); - for (d = domains.begin(); d != end; ++d) { - domainNames.push_back(d->_key); - } - - return domainNames; -} - diff --git a/common/config-file.h b/common/config-file.h deleted file mode 100644 index bfec3e8465..0000000000 --- a/common/config-file.h +++ /dev/null @@ -1,70 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2001 Ludvig Strigeus - * Copyright (C) 2001-2003 The ScummVM project - * - * 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 the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * 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. - * - * $Header$ - * - */ - -#ifndef CONFIG_FILE_H -#define CONFIG_FILE_H - -#include "common/list.h" -#include "common/map.h" -#include "common/str.h" -#include "common/util.h" - -class Config { -public: - typedef Common::String String; - typedef Common::StringList StringList; - typedef Common::StringMap StringMap; - typedef Common::Map<String, StringMap> DomainMap; - - Config (const String & = String("config.cfg"), const String & = String("default")); - const char *get(const String &key, const String &dom = String()) const; - const int getInt(const String &key, int def = 0, const String &dom = String()) const; - const bool getBool(const String &key, bool def = false, const String &dom = String()) const; - - void set(const String &key, const String &value, const String &dom = String()); - void setInt(const String &key, int value, const String &dom = String()); - void setBool(const String &key, bool value, const String &dom = String()); - - void set_domain(const String &d); - void flush() const; - void rename_domain(const String &oldD, const String &newD); - void delete_domain(const String &d); - bool has_domain(const String &d) const; - void set_filename(const String &); - void merge_config(const Config &); - void set_writing(bool); - - const int count_domains(); - StringList get_domains(); - -protected: - DomainMap domains; - String filename; - String defaultDomain; - - bool willwrite; -}; - -// The global config object -extern Config *g_config; - -#endif diff --git a/common/config-manager.cpp b/common/config-manager.cpp new file mode 100644 index 0000000000..f90eefbbd3 --- /dev/null +++ b/common/config-manager.cpp @@ -0,0 +1,370 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2001 Ludvig Strigeus + * Copyright (C) 2001-2003 The ScummVM project + * + * 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 the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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. + * + * $Header$ + * + */ + +#include "common/config-manager.h" + +#if defined(UNIX) +#include <sys/param.h> +#ifndef MAXPATHLEN +#define MAXPATHLEN 256 +#endif +#ifdef MACOSX +#define DEFAULT_CONFIG_FILE "Library/Preferences/ScummVM Preferences" +#else +#define DEFAULT_CONFIG_FILE ".scummvmrc" +#endif +#else +#define DEFAULT_CONFIG_FILE "scummvm.ini" +#endif + +#define MAXLINELEN 256 + +static char *ltrim(char *t) { + while (*t == ' ') + t++; + return t; +} + +static char *rtrim(char *t) { + int l = strlen(t) - 1; + while (l >= 0 && t[l] == ' ') + t[l--] = 0; + return t; +} + + +namespace Common { + +const String ConfigManager::kApplicationDomain("scummvm"); + +const String trueStr("true"); +const String falseStr("false"); + + +#pragma mark - + + +ConfigManager::ConfigManager() { + +#if defined(UNIX) + char configFile[MAXPATHLEN]; + if(getenv("HOME") != NULL) + sprintf(configFile,"%s/%s", getenv("HOME"), DEFAULT_CONFIG_FILE); + else strcpy(configFile,DEFAULT_CONFIG_FILE); +#else + char configFile[256]; + #if defined (WIN32) && !defined(_WIN32_WCE) + GetWindowsDirectory(configFile, 256); + strcat(configFile, "\\"); + strcat(configFile, DEFAULT_CONFIG_FILE); + #elif defined(__PALM_OS__) + strcpy(configFile,"/PALM/Programs/ScummVM/"); + strcat(configFile, DEFAULT_CONFIG_FILE); + #else + strcpy(configFile, DEFAULT_CONFIG_FILE); + #endif +#endif + + // Ensure the global domain(s) are setup. + _globalDomains.addKey(kApplicationDomain); +#ifdef _WIN32_WCE + // WinCE for some reasons uses additional global domains. + _globalDomains.addKey("wince"); + _globalDomains.addKey("smartfon-keys"); +#endif + + _filename = configFile; + loadFile(_filename); +} + +void ConfigManager::loadFile(const String &filename) { + FILE *cfg_file; + char t[MAXLINELEN]; + String domain; + + if (!(cfg_file = fopen(filename.c_str(), "r"))) { + debug(1, "Unable to open configuration file: %s.\n", filename.c_str()); + } else { + while (!feof(cfg_file)) { + if (!fgets(t, MAXLINELEN, cfg_file)) + continue; + if (t[0] != '#') { + if (t[0] == '[') { + // It's a new domain which begins here. + char *p = strchr(t, ']'); + if (!p) { + error("Config file buggy: no ] at the end of the domain name.\n"); + } else { + *p = 0; + // TODO: Some kind of domain name verification might be nice. + // E.g. restrict to only a-zA-Z0-9 and maybe -_ or so... + domain = t + 1; + } + } else { + // It's a new key in the domain. + if (domain.isEmpty()) { + error("Config file buggy: we have a key without a domain first.\n"); + } + char *p = strchr(t, '\n'); + if (p) + *p = 0; + p = strchr(t, '\r'); + if (p) + *p = 0; + + if (!(p = strchr(t, '='))) { + if (strlen(t)) + warning("Config file buggy: there is junk: %s\n", t); + } else { + *p = 0; + String key = ltrim(rtrim(t)); + String value = ltrim(p + 1); + set(key, value, domain); + } + } + } + } + fclose(cfg_file); + } +} + +void ConfigManager::flushToDisk() { + FILE *cfg_file; + +// TODO +// if (!willwrite) +// return; + + if (!(cfg_file = fopen(_filename.c_str(), "w"))) { + warning("Unable to write configuration file: %s.\n", _filename.c_str()); + } else { + DomainMap::ConstIterator d; + + // First write the global domains + for (d = _globalDomains.begin(); d != _globalDomains.end(); ++d) { + writeDomain(cfg_file, d->_key, d->_value); + } + + // Second, write the game domains + for (d = _gameDomains.begin(); d != _gameDomains.end(); ++d) { + writeDomain(cfg_file, d->_key, d->_value); + } + + fclose(cfg_file); + } +} + +void ConfigManager::writeDomain(FILE *file, const String &name, const Domain &domain) { + if (domain.isEmpty()) + return; // Don't bother writing empty domains. + + fprintf(file, "[%s]\n", name.c_str()); + + StringMap::ConstIterator x; + for (x = domain.begin(); x != domain.end(); ++x) { + const String &value = x->_value; + if (!value.isEmpty()) + fprintf(file, "%s=%s\n", x->_key.c_str(), value.c_str()); + } + fprintf(file, "\n"); +} + +#pragma mark - + + +bool ConfigManager::hasKey(const String &key) const { + // Search the domains in the following order: + // 1) Run time domain + // 2) Active game domain (if any) + // 3) All global domains + // The defaults domain is explicitly *not* checked. + +// if (_runtimeDomain.contain(key)) +// return true; + + if (!_activeDomain.isEmpty() && _gameDomains[_activeDomain].contains(key)) + return true; + + DomainMap::ConstIterator iter; + for (iter = _globalDomains.begin(); iter != _globalDomains.end(); ++iter) { + if (iter->_value.contains(key)) + return true; + } + + return false; +} + + +bool ConfigManager::hasKey(const String &key, const String &dom) const { + assert(!dom.isEmpty()); + + if (_gameDomains.contains(dom)) + return _gameDomains[dom].contains(key); + if (_globalDomains.contains(dom)) + return _globalDomains[dom].contains(key); + + return false; +} + + +#pragma mark - + + +const String & ConfigManager::get(const String &key) const { + // Search the domains in the following order: + // 1) Run time domain + // 2) Active game domain (if any) + // 3) All global domains + // 4) The defaults + +// if (_runtimeDomain.contain(key)) +// return true; + + if (!_activeDomain.isEmpty() && _gameDomains[_activeDomain].contains(key)) + return _gameDomains[_activeDomain][key]; + + DomainMap::ConstIterator iter; + for (iter = _globalDomains.begin(); iter != _globalDomains.end(); ++iter) { + if (iter->_value.contains(key)) + return iter->_value[key]; + } + + return _defaultsDomain.get(key); +} + +const String & ConfigManager::get(const String &key, const String &dom) const { + if (dom.isEmpty()) + return get(key); + + // TODO: How exactly should we handle the case were the domain 'dom' + // is not found, or were dom is found, but doesn't contain 'key' ? + // Right now we just return an empty string. But might want to print + // out a warning, or even error out? + if (_gameDomains.contains(dom)) + return _gameDomains[dom].get(key); + if (_globalDomains.contains(dom)) + return _globalDomains[dom].get(key); + + return String::emptyString; +} + +int ConfigManager::getInt(const String &key, const String &dom) const { + String value(get(key, dom)); + // Convert the string to an integer. + // TODO: We should perform some error checking. + long v = strtol(value.c_str(), 0, 10); + return (int)v; +} + +bool ConfigManager::getBool(const String &key, const String &dom) const { + String value(get(key, dom)); + // '1', 'true' and 'yes' are accepted as true values; everything else + // maps to value 'false'. + return (value == "true") || (value == "yes") || (value == "1"); +} + + +#pragma mark - + + +void ConfigManager::set(const String &key, const String &value) { +#if 0 + // TODO ?!? +// _runtimeDomain[key] = value; +#else + if (_activeDomain.isEmpty()) + _globalDomains[kApplicationDomain][key] = value; + else + _gameDomains[_activeDomain][key] = value; +#endif +} + +void ConfigManager::set(const String &key, const String &value, const String &dom) { + if (_globalDomains.contains(dom)) + _globalDomains[dom][key] = value; + else + _gameDomains[dom][key] = value; +} + +void ConfigManager::set(const String &key, const char *value, const String &dom) { + set(key, String(value), dom); +} + +void ConfigManager::set(const String &key, int value, const String &dom) { + char tmp[128]; + snprintf(tmp, sizeof(tmp), "%i", value); + set(key, String(tmp), dom); +} + +void ConfigManager::set(const String &key, bool value, const String &dom) { + set(key, value ? trueStr : falseStr, dom); +} + + +#pragma mark - + + +void ConfigManager::registerDefault(const String &key, const String &value) { + _defaultsDomain[key] = value; +} + +void ConfigManager::registerDefault(const String &key, const char *value) { + registerDefault(key, String(value)); +} + +void ConfigManager::registerDefault(const String &key, int value) { + char tmp[128]; + snprintf(tmp, sizeof(tmp), "%i", value); + registerDefault(key, tmp); +} + +void ConfigManager::registerDefault(const String &key, bool value) { + registerDefault(key, value ? trueStr : falseStr); +} + + +#pragma mark - + + +void ConfigManager::setActiveDomain(const String &domain) { + _activeDomain = domain; + _gameDomains.addKey(domain); +} + +void ConfigManager::removeGameDomain(const String &name) { + _gameDomains.remove(name); +} + +void ConfigManager::renameGameDomain(const String &oldName, const String &newName) { + if (oldName == newName) + return; + + _gameDomains[newName].merge(_gameDomains[oldName]); + + _gameDomains.remove(oldName); +} + +bool ConfigManager::hasGameDomain(const String &domain) const { + return _gameDomains.contains(domain); +} + +} // End of namespace Common diff --git a/common/config-manager.h b/common/config-manager.h new file mode 100644 index 0000000000..d4d368e761 --- /dev/null +++ b/common/config-manager.h @@ -0,0 +1,127 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2001 Ludvig Strigeus + * Copyright (C) 2001-2003 The ScummVM project + * + * 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 the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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. + * + * $Header$ + * + */ + +#ifndef COMMON_CONFIG_H +#define COMMON_CONFIG_H + +#include "common/list.h" +#include "common/map.h" +#include "common/singleton.h" +#include "common/str.h" +#include "common/util.h" + +namespace Common { + +class File; + + +/** + * The (singleton) configuration manager, used to query & set configuration + * values using string keys. + * + * @todo Implement the callback based notification system (outline below) + * which sends out notifications to interested parties whenever the value + * of some specific (or any) configuration key changes. + */ +class ConfigManager : public Singleton<ConfigManager> { +public: + class Domain : public StringMap { +// friend class ConfigManager; + public: + const String &get(const String &key) const { + Node *node = findNode(_root, key); + return node ? node->_value : String::emptyString; + } +/* + void set(const String &key, const String &value); + void set(const String &key, int value); + void set(const String &key, bool value); +*/ + }; + + typedef Map<String, Domain> DomainMap; + + /** The name of the application domain (normally 'scummvm'). */ + static const String kApplicationDomain; + + bool hasKey(const String &key) const; + bool hasKey(const String &key, const String &dom) const; + + const String & get(const String &key) const; + const String & get(const String &key, const String &dom) const; + int getInt(const String &key, const String &dom = String::emptyString) const; + bool getBool(const String &key, const String &dom = String::emptyString) const; + + void set(const String &key, const String &value); + void set(const String &key, const String &value, const String &dom); + void set(const String &key, const char *value, const String &dom = String::emptyString); + void set(const String &key, int value, const String &dom = String::emptyString); + void set(const String &key, bool value, const String &dom = String::emptyString); + + void registerDefault(const String &key, const String &value); + void registerDefault(const String &key, const char *value); + void registerDefault(const String &key, int value); + void registerDefault(const String &key, bool value); +// ... + + void flushToDisk(); + + void setActiveDomain(const String &domain); + +// void addDomain(const String &name); + void removeGameDomain(const String &name); + void renameGameDomain(const String &oldName, const String &newName); + bool hasGameDomain(const String &domain) const; + const DomainMap & getGameDomains() const { return _gameDomains; } + +/* + TODO: Callback/change notification system + typedef void (*ConfigCallback)(const ConstString &key, void *refCon); + + void registerCallback(const ConstString &key, ConfigCallback cfgc, void *refCon) + void unregisterCallback(const ConstString &key, ConfigCallback cfgc) +*/ + +private: + friend class Singleton<ConfigManager>; + ConfigManager(); + + void loadFile(const String &filename); + void writeDomain(FILE *file, const String &name, const Domain &domain); + +// Domain _runtimeDomain; + DomainMap _gameDomains; + DomainMap _globalDomains; + Domain _defaultsDomain; + + List<Domain *> _searchOrder; + + String _activeDomain; + String _filename; +}; + +} // End of namespace Common + +/** Shortcut for accessing the configuration manager. */ +#define ConfMan Common::ConfigManager::instance() + +#endif diff --git a/common/module.mk b/common/module.mk index 4bb6e6e1e5..b55428edab 100644 --- a/common/module.mk +++ b/common/module.mk @@ -1,7 +1,7 @@ MODULE := common MODULE_OBJS := \ - common/config-file.o \ + common/config-manager.o \ common/file.o \ common/scaler.o \ common/str.o \ diff --git a/common/singleton.h b/common/singleton.h new file mode 100644 index 0000000000..be40b45f42 --- /dev/null +++ b/common/singleton.h @@ -0,0 +1,57 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2001 Ludvig Strigeus + * Copyright (C) 2001-2003 The ScummVM project + * + * 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 the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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. + * + * $Header$ + * + */ + +#ifndef COMMON_SINGLETON_H +#define COMMON_SINGLETON_H + +namespace Common { + +/** + * Generic template base class for implementing the singleton design pattern. + */ +template <class T> +class Singleton +{ +public: + static T& instance() { + // TODO: We aren't thread safe. For now we ignore it since the + // only thing using this singleton template is the config manager, + // and that is first instantiated long before any threads. + // TODO: We don't leak, but the destruction order is nevertheless + // semi-random. If we use multiple singletons, the destruction + // order might become an issue. There are various approaches + // to solve that problem, but for now this is sufficient + static T singleton; + return singleton; + } +protected: + Singleton<T>() { } + ~Singleton<T>() { } + +private: + Singleton(const Singleton&); + Singleton& operator= (const Singleton&); +}; + +} // End of namespace Common + +#endif |