reduce verbosity
[gnash.git] / libbase / GnashFactory.h
blob41cfae9c68db166117f237b54f0328616b5b1a20
1 // GnashFactory.h A generic class template
2 //
3 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
4 // Foundation, Inc
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #ifndef GNASH_FACTORY_H
22 #define GNASH_FACTORY_H
24 #ifdef HAVE_CONFIG_H
25 # include "gnashconfig.h"
26 #endif
28 #include <map>
29 #include <string>
30 #include <algorithm>
31 #include <iterator>
32 #include <boost/type_traits.hpp>
33 #include <boost/utility/enable_if.hpp>
35 #include "dsodefs.h"
36 #include "GnashAlgorithm.h"
38 namespace gnash {
41 /// A generic factory class for registering and retrieving objects by key.
43 /// Note: there is only one GnashFactory for any combination of template
44 /// arguments. It's not advisable to have more than one factory for any
45 /// type.
47 /// Note that this relies on static initialization, so do not call get()
48 /// before or after main().
50 /// @tparam T The base type to be produced by the factory
51 /// @tparam Init An object whose constructor ensures that the elements
52 /// are registered. This helps avoid problems with
53 /// unpredictable static initialization.
54 /// @tparam Key The type to be used as a key.
55 template<typename T, typename Init = void, typename Key = std::string>
56 class DSOEXPORT GnashFactory
58 public:
60 typedef T value_type;
61 typedef Key key_type;
63 template<typename Derived>
64 struct RegisterHandler
66 static T* createHandler() {
67 return new Derived();
70 RegisterHandler(const Key& name) {
71 GnashFactory::instance().registerHandler(name, createHandler);
75 typedef T*(*CreateHandler)();
76 typedef std::map<std::string, CreateHandler> Handlers;
78 /// Get the GnashFactory singleton.
79 static GnashFactory& instance() {
80 static GnashFactory m;
81 return m;
84 /// Dump the registered keys to the iterator.
86 /// Only usable with output iterators.
87 template<typename Iterator>
88 void listKeys(Iterator i, typename boost::enable_if<boost::is_same<
89 typename std::iterator_traits<Iterator>::iterator_category,
90 std::output_iterator_tag> >::type* dummy = 0) {
91 Init();
92 static_cast<void>(dummy);
93 std::transform(_handlers.begin(), _handlers.end(), i,
94 FirstElement<typename Handlers::value_type>());
98 /// Return a Handler identified by a name.
100 /// @param name The name of the handler to return. An empty string
101 /// will return the first available handler. If the
102 /// string is not empty and no match is found, a null
103 /// pointer will be returned.
104 T* get(const Key& name) {
105 Init();
106 if (name.empty()) {
107 return _handlers.empty() ? 0 : _handlers.begin()->second();
110 typename Handlers::const_iterator it = _handlers.find(name);
111 if (it == _handlers.end()) return 0;
112 return it->second();
115 /// Register a Handler with a particular name.
117 /// @param name The name to register the Handler under. Duplicated
118 /// names will replace previous handlers!
119 /// @param r A pointer to a function that will return the
120 /// Handler when called.
121 void registerHandler(const Key& name, CreateHandler r) {
122 _handlers[name] = r;
125 private:
127 GnashFactory() {}
129 Handlers _handlers;
133 } // namespace gnash
135 #endif