diff options
author | Karsten Heimrich <karsten.heimrich@theqtcompany.com> | 2015-06-25 11:37:04 +0200 |
---|---|---|
committer | Karsten Heimrich <karsten.heimrich@theqtcompany.com> | 2015-06-25 15:32:46 +0000 |
commit | 38bd4ceae105f45dc4cb42ddea65fcc16f946830 (patch) | |
tree | b9468f5d73a4eb1ce8e3ac10d437ad074cc1ea19 /src/libs | |
parent | 5d53c5a4ba362c6281da869c0a04a6c47cb54d52 (diff) |
Implement generic factory using c++11 variadic template feature.
Change-Id: I65bbb82ef1bd8c1a94100b583f504a86d64015de
Reviewed-by: Niels Weber <niels.weber@theqtcompany.com>
Reviewed-by: Kai Koehne <kai.koehne@theqtcompany.com>
Diffstat (limited to 'src/libs')
-rw-r--r-- | src/libs/installer/packagemanagerpagefactory.cpp | 5 | ||||
-rw-r--r-- | src/libs/installer/packagemanagerpagefactory.h | 13 | ||||
-rw-r--r-- | src/libs/kdtools/kdgenericfactory.cpp | 124 | ||||
-rw-r--r-- | src/libs/kdtools/kdgenericfactory.h | 61 | ||||
-rw-r--r-- | src/libs/kdtools/kdupdaterfiledownloaderfactory.cpp | 5 | ||||
-rw-r--r-- | src/libs/kdtools/kdupdaterfiledownloaderfactory.h | 3 |
6 files changed, 36 insertions, 175 deletions
diff --git a/src/libs/installer/packagemanagerpagefactory.cpp b/src/libs/installer/packagemanagerpagefactory.cpp index 71b05b349..37aff9aae 100644 --- a/src/libs/installer/packagemanagerpagefactory.cpp +++ b/src/libs/installer/packagemanagerpagefactory.cpp @@ -42,9 +42,4 @@ PackageManagerPageFactory &PackageManagerPageFactory::instance() return factory; } -PackageManagerPage *PackageManagerPageFactory::create(int id, PackageManagerCore *core) const -{ - return KDGenericFactory<PackageManagerPage, int, PackageManagerCore*>::createWithArg(id, core); -} - } diff --git a/src/libs/installer/packagemanagerpagefactory.h b/src/libs/installer/packagemanagerpagefactory.h index b7015ffe4..ee8b8ff66 100644 --- a/src/libs/installer/packagemanagerpagefactory.h +++ b/src/libs/installer/packagemanagerpagefactory.h @@ -35,16 +35,16 @@ #ifndef PACKAGEMANAGERPAGEFACTORY_H #define PACKAGEMANAGERPAGEFACTORY_H -#include <kdgenericfactory.h> -#include <packagemanagergui.h> +#include "kdgenericfactory.h" +#include "qinstallerglobal.h" namespace QInstaller { class PackageManagerCore; class PackageManagerPage; -class INSTALLER_EXPORT PackageManagerPageFactory : public KDGenericFactory<PackageManagerPage, - int, QInstaller::PackageManagerCore*> +class INSTALLER_EXPORT PackageManagerPageFactory : public KDGenericFactory<PackageManagerPage, int, + PackageManagerCore*> { Q_DISABLE_COPY(PackageManagerPageFactory) @@ -52,12 +52,11 @@ public: static PackageManagerPageFactory &instance(); template<typename T> void registerPackageManagerPage(int id) { - registerProductWithArg<T>(id); + registerProduct<T>(id); } - PackageManagerPage *create(int id, QInstaller::PackageManagerCore *core) const; private: - PackageManagerPageFactory() {} + PackageManagerPageFactory() = default; }; } // namespace QInstaller diff --git a/src/libs/kdtools/kdgenericfactory.cpp b/src/libs/kdtools/kdgenericfactory.cpp index 7cc8f38f0..9dbfc101d 100644 --- a/src/libs/kdtools/kdgenericfactory.cpp +++ b/src/libs/kdtools/kdgenericfactory.cpp @@ -44,86 +44,6 @@ factory registers those producible classes in the factory by using an identifier \c T_Identifier. That identifier can then be used to produce as many instances of the registered product as the user wants. - - The advanced user can even choose the type of the class the factory is using to store its - FactoryFunctions by passing a \c T_Map template parameter. It defaults to QHash. - - KDGenericFactory expects the storage container to be a template class accepting \c T_Identifier - and \c FactoryFunction as parameters. Additionally it needs to provide: - - \table - \header - \li Method - \li Description - \row - \li \c {const_iterator} - \li A type that provides a random-access iterator that can read a const element and - when dereferenced has type \c {const &FactoryFunction}. - \row - \li \c {insert(T_Identifier, FactoryFunction)} - \li A function that inserts a new item with \c T_Identifier as key and \c FactoryFunction - as value. If there is already an item with \c T_Identifier as key, that item's value - must be replaced with \c FactoryFunction. - \row - \li \c {find(T_Identifier)} - \li A function returning an iterator pointing to the item with the key \c T_Identifier. - - \row - \li \c {end()} - \li A function returning an iterator pointing to the imaginary item after the last item. - - \row - \li \c {size()} - \li A function returning the number of items. - \row - \li \c {remove(T_Identifier)} - \li A function removing all items that have the key \c T_Identifier. - \row - \li \c {keys()} - \li A function returning a list of all the keys \c T_Identifier in an arbitrary order. - \endtable - - The only two class templates that currently match this concept are QHash and QMap. QMultiHash - and QMultiMap do not work, because they violate the requirement on insert() above and std::map - and std::unordered_map do not match, because they do not have keys() and, because a dereferenced - iterator has type \c {std::pair<const T_Identifier, FactoryFunction>} instead of just - \c FactoryFunction. - - The following example shows how the general use case of KDGenericFactory looks like: - - \code - - class Fruit - { - }; - - class Apple : public Fruit - { - }; - - class Pear : public Fruit - { - }; - - int main() - { - // creates a common fruit "factory" - KDGenericFactory< Fruit > fruitPlantation; - // registers the product "Apple" - fruitPlantation.registerProduct< Apple >( "Apple" ); - // registers the product "Pear" - fruitPlantation.registerProduct< Pear >( "Pear" ); - - // lets create some stuff - here comes our tasty apple: - Fruit* myApple = fruitPlantation.create( "Apple" ); - - // and a pear, please: - Fruit* myPear = fruitPlantation.create( "Pear" ); - - // ohh - that doesn't work, returns a null pointer: - Fruit* myCherry = fruitPlantation.create( "Cherry" ); - } - \endcode */ /*! @@ -139,49 +59,21 @@ */ /*! - \typedef KDGenericFactory::FactoryFunctionWithArg - - This typedef defines a factory function producing an object of type T_Product - with the arguments specified by \a arg. -*/ - -/*! - \fn KDGenericFactory::registerProduct( const T_Identifier& name ) - - Registers a product of the type T, identified by \a name in the factory. - Any type with the same name gets unregistered. - - If a product was registered via this method, it will be created using its - default constructor. -*/ - -/*! - \fn KDGenericFactory::registerProductWithArg(const T_Identifier &name) - - Registers a product of the type T, identified by \a name, with arguments. - Any type with the same name gets unregistered. - - If a product was registered via this method, it will be created using its - default constructor. -*/ - -/*! - \fn bool KDGenericFactory::containsProduct(const T_Identifier &name) const + \fn KDGenericFactory::registerProduct(const T_Identifier &id) - Returns \c true if the factory contains a product with the \a name; otherwise returns false. + Registers a product of the type T, identified by \a id in the factory. Any type with the same id + gets unregistered. */ /*! - \fn KDGenericFactory::create( const T_Identifier& name ) const + \fn bool KDGenericFactory::containsProduct(const T_Identifier &id) const - Creates and returns a product of the type T identified by \a name. - Ownership of the product is transferred to the caller. + Returns \c true if the factory contains a product with the \a id; otherwise returns false. */ /*! - \fn KDGenericFactory::createWithArg(const T_Identifier &name, const T_Argument &arg) const + \fn KDGenericFactory::create(const T_Identifier &id) const - Creates and returns a product of the type T identified by \a name with the - arguments specified by \a arg. - Ownership of the product is transferred to the caller. + Creates and returns a product of the type T identified by \a id. Ownership of the product is + transferred to the caller. */ diff --git a/src/libs/kdtools/kdgenericfactory.h b/src/libs/kdtools/kdgenericfactory.h index 0417dfcb6..719a4f9da 100644 --- a/src/libs/kdtools/kdgenericfactory.h +++ b/src/libs/kdtools/kdgenericfactory.h @@ -39,73 +39,48 @@ #include <QtCore/QHash> -template <typename T_Product, typename T_Identifier = QString, typename T_Argument = QString> +template <typename T_Product, typename T_Identifier = QString, typename... T_Argument> class KDGenericFactory { public: virtual ~KDGenericFactory() {} - typedef T_Product *(*FactoryFunction)(); - typedef T_Product *(*FactoryFunctionWithArg)(const T_Argument &arg); + typedef T_Product *(*FactoryFunction)(T_Argument...); template <typename T> - void registerProduct(const T_Identifier &name) + void registerProduct(const T_Identifier &id) { -#ifdef Q_CC_MSVC - FactoryFunction function = &KDGenericFactory::create<T>; -#else // compile fix for old gcc - FactoryFunction function = &create<T>; -#endif - map.insert(name, function); + m_hash.insert(id, &KDGenericFactory::create<T>); } - bool containsProduct(const T_Identifier &name) const + bool containsProduct(const T_Identifier &id) const { - return map.contains(name) | map2.contains(name); + return m_hash.contains(id); } - T_Product *create(const T_Identifier &name) const + T_Product *create(const T_Identifier &id, T_Argument... args) const { - const typename QHash<T_Identifier, FactoryFunction>::const_iterator it = map.find(name); - if (it == map.end()) + const auto it = m_hash.constFind(id); + if (it == m_hash.constEnd()) return 0; - return (*it)(); + return (*it)(args...); } - template <typename T> - void registerProductWithArg(const T_Identifier &name) - { -#ifdef Q_CC_MSVC - FactoryFunctionWithArg function = &KDGenericFactory::create<T>; -#else // compile fix for old gcc - FactoryFunctionWithArg function = &create<T>; -#endif - map2.insert(name, function); - } - - T_Product *createWithArg(const T_Identifier &name, const T_Argument &arg) const - { - const typename QHash<T_Identifier, FactoryFunctionWithArg>::const_iterator it = map2.find(name); - if (it == map2.end()) - return 0; - return (*it)(arg); - } +protected: + KDGenericFactory() = default; private: template <typename T> - static T_Product *create() + static T_Product *create(T_Argument... args) { - return new T; + return new T(args...); } - template <typename T> - static T_Product *create(const T_Argument &arg) - { - return new T(arg); - } + KDGenericFactory(const KDGenericFactory &) = delete; + KDGenericFactory &operator=(const KDGenericFactory &) = delete; - QHash<T_Identifier, FactoryFunction> map; - QHash<T_Identifier, FactoryFunctionWithArg> map2; +private: + QHash<T_Identifier, FactoryFunction> m_hash; }; #endif diff --git a/src/libs/kdtools/kdupdaterfiledownloaderfactory.cpp b/src/libs/kdtools/kdupdaterfiledownloaderfactory.cpp index 2321e7667..73eb4c02f 100644 --- a/src/libs/kdtools/kdupdaterfiledownloaderfactory.cpp +++ b/src/libs/kdtools/kdupdaterfiledownloaderfactory.cpp @@ -155,10 +155,9 @@ bool FileDownloaderFactory::isSupportedScheme(const QString &scheme) */ FileDownloader *FileDownloaderFactory::create(const QString &scheme, QObject *parent) const { - FileDownloader *downloader = KDGenericFactory<FileDownloader>::create(scheme); + FileDownloader *downloader = + KDGenericFactory<FileDownloader, QString, QObject*>::create(scheme, parent); if (downloader != 0) { - downloader->setParent(parent); - downloader->setScheme(scheme); downloader->setFollowRedirects(d->m_followRedirects); downloader->setIgnoreSslErrors(d->m_ignoreSslErrors); if (d->m_factory) diff --git a/src/libs/kdtools/kdupdaterfiledownloaderfactory.h b/src/libs/kdtools/kdupdaterfiledownloaderfactory.h index ea85f2a05..ad0aa00d0 100644 --- a/src/libs/kdtools/kdupdaterfiledownloaderfactory.h +++ b/src/libs/kdtools/kdupdaterfiledownloaderfactory.h @@ -58,7 +58,8 @@ public: virtual FileDownloaderProxyFactory *clone() const = 0; }; -class KDTOOLS_EXPORT FileDownloaderFactory : public KDGenericFactory<FileDownloader> +class KDTOOLS_EXPORT FileDownloaderFactory : public KDGenericFactory<FileDownloader, QString, + QObject*> { Q_DISABLE_COPY(FileDownloaderFactory) struct FileDownloaderFactoryData { |