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 : #include <boost/functional/factory.hpp>
31 :
32 : namespace lunchbox
33 : {
34 : /**
35 : * Helper class to statically register derived plugin classes. If MyInitDataType
36 : * is not given, default value is servus::URI.
37 : *
38 : * The following code can be placed in a plugin's cpp file:
39 : * @code
40 : * namespace
41 : * {
42 : * PluginRegisterer< MyPluginInterface > registerer;
43 : * }
44 : * @endcode
45 : *
46 : * Also note that it needs the following type definition to be placed in the
47 : * plugin's interface (or in all its implementations that are to be registered):
48 : * @code
49 : * class MyPluginInterface
50 : * {
51 : * public:
52 : * typedef MyPluginInterface PluginT;
53 : * typedef MyPluginInitData InitDataT;
54 : * ( optional for InitDataT == servus::URI )
55 : * }
56 : * @endcode
57 : *
58 : * @version 1.11.0
59 : */
60 : template< typename T > struct hasInitDataT
61 : {
62 : // SFINAE class to check whether class T has a typedef InitDataT
63 : // If class has the typedef, "value" is known in compile time as true,
64 : // else value is false.
65 :
66 : // SFINAE is used for specializing the PluginRegisterer class
67 : // when no InitDataT is defined.
68 : template<typename U> static char (&test(typename U::InitDataT const*))[1];
69 : template<typename U> static char (&test(...))[2];
70 : // cppcheck-suppress sizeofCalculation
71 : static const bool value = (sizeof(test<T>(0)) == 1);
72 : };
73 :
74 : template< typename Impl, bool hasInitData = hasInitDataT< Impl >::value >
75 : class PluginRegisterer
76 : {
77 : public:
78 : /** Construct a registerer and register the Impl class. @version 1.11.0 */
79 : PluginRegisterer();
80 : };
81 :
82 : /**
83 : * Specialized PluginRegisterer for implementations which have the InitDataT
84 : * definition.
85 : */
86 : template< typename Impl > class PluginRegisterer< Impl, true >
87 : {
88 : public:
89 : /** Construct a registerer and register the Impl class. @version 1.11.0 */
90 4 : PluginRegisterer()
91 : {
92 : Plugin< typename Impl::PluginT, typename Impl::InitDataT > plugin(
93 : boost::bind( boost::factory< Impl* >(), _1 ),
94 4 : boost::bind( &Impl::handles, _1 ));
95 4 : PluginFactory< typename Impl::PluginT,
96 4 : typename Impl::InitDataT >::getInstance().
97 4 : register_( plugin );
98 4 : }
99 : };
100 :
101 : /**
102 : * Specialized PluginRegisterer for plugin implementations which don't have
103 : * the InitDataT definition.
104 : */
105 : template< typename Impl > class PluginRegisterer< Impl, false >
106 : {
107 : public:
108 : /** Construct a registerer and register the Impl class. @version 1.11.0 */
109 4 : PluginRegisterer()
110 : {
111 : Plugin< typename Impl::PluginT > plugin(
112 : boost::bind( boost::factory< Impl* >(), _1 ),
113 4 : boost::bind( &Impl::handles, _1 ));
114 :
115 4 : PluginFactory< typename Impl::PluginT >::getInstance().
116 4 : register_( plugin );
117 4 : }
118 : };
119 :
120 : }
121 :
122 : #endif
|