Line data Source code
1 :
2 : /* Copyright (c) 2013-2015, EPFL/Blue Brain Project
3 : * Raphael Dumusc <raphael.dumusc@epfl.ch>
4 : * Stefan.Eilemann@epfl.ch
5 : *
6 : * This file is part of Lunchbox <https://github.com/Eyescale/Lunchbox>
7 : *
8 : * This library is free software; you can redistribute it and/or modify it under
9 : * the terms of the GNU Lesser General Public License version 2.1 as published
10 : * by the Free Software Foundation.
11 : *
12 : * This library is distributed in the hope that it will be useful, but WITHOUT
13 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
15 : * details.
16 : *
17 : * You should have received a copy of the GNU Lesser General Public License
18 : * along with this library; if not, write to the Free Software Foundation, Inc.,
19 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 : */
21 :
22 : #ifndef LUNCHBOX_PLUGINREGISTERER_H
23 : #define LUNCHBOX_PLUGINREGISTERER_H
24 :
25 : #include <lunchbox/plugin.h> // used inline
26 : #include <lunchbox/pluginFactory.h> // used inline
27 :
28 : #include <boost/bind.hpp> // used inline
29 : #include <boost/version.hpp>
30 : #if BOOST_VERSION >= 104300
31 : # include <boost/functional/factory.hpp>
32 : #else
33 : # include <lunchbox/factory.hpp>
34 : #endif
35 :
36 : namespace lunchbox
37 : {
38 : /**
39 : * Helper class to statically register derived plugin classes. If MyInitDataType
40 : * is not given, default value is servus::URI.
41 : *
42 : * The following code can be placed in a plugin's cpp file:
43 : * @code
44 : * namespace
45 : * {
46 : * PluginRegisterer< MyPluginInterface > registerer;
47 : * }
48 : * @endcode
49 : *
50 : * Also note that it needs the following type definition to be placed in the
51 : * plugin's interface (or in all its implementations that are to be registered):
52 : * @code
53 : * class MyPluginInterface
54 : * {
55 : * public:
56 : * typedef MyPluginInterface PluginT;
57 : * typedef MyPluginInitData InitDataT;
58 : * ( optional for InitDataT == servus::URI )
59 : * }
60 : * @endcode
61 : *
62 : * @version 1.11.0
63 : */
64 : template< typename T > struct hasInitDataT
65 : {
66 : // SFINAE class to check whether class T has a typedef InitDataT
67 : // If class has the typedef, "value" is known in compile time as true,
68 : // else value is false.
69 :
70 : // SFINAE is used for specializing the PluginRegisterer class
71 : // when no InitDataT is defined.
72 : template<typename U> static char (&test(typename U::InitDataT const*))[1];
73 : template<typename U> static char (&test(...))[2];
74 : // cppcheck-suppress sizeofCalculation
75 : static const bool value = (sizeof(test<T>(0)) == 1);
76 : };
77 :
78 : template< typename Impl, bool hasInitData = hasInitDataT< Impl >::value >
79 : class PluginRegisterer
80 : {
81 : public:
82 : /** Construct a registerer and register the Impl class. @version 1.11.0 */
83 : PluginRegisterer();
84 : };
85 :
86 : /**
87 : * Specialized PluginRegisterer for implementations which have the InitDataT
88 : * definition.
89 : */
90 : template< typename Impl > class PluginRegisterer< Impl, true >
91 : {
92 : public:
93 : /** Construct a registerer and register the Impl class. @version 1.11.0 */
94 4 : PluginRegisterer()
95 : {
96 : Plugin< typename Impl::PluginT, typename Impl::InitDataT > plugin(
97 : boost::bind( boost::factory< Impl* >(), _1 ),
98 4 : boost::bind( &Impl::handles, _1 ));
99 4 : PluginFactory< typename Impl::PluginT,
100 4 : typename Impl::InitDataT >::getInstance().
101 4 : register_( plugin );
102 4 : }
103 : };
104 :
105 : /**
106 : * Specialized PluginRegisterer for plugin implementations which don't have
107 : * the InitDataT definition.
108 : */
109 : template< typename Impl > class PluginRegisterer< Impl, false >
110 : {
111 : public:
112 : /** Construct a registerer and register the Impl class. @version 1.11.0 */
113 4 : PluginRegisterer()
114 : {
115 : Plugin< typename Impl::PluginT > plugin(
116 : boost::bind( boost::factory< Impl* >(), _1 ),
117 4 : boost::bind( &Impl::handles, _1 ));
118 :
119 4 : PluginFactory< typename Impl::PluginT >::getInstance().
120 4 : register_( plugin );
121 4 : }
122 : };
123 :
124 : }
125 :
126 : #endif
|