• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

STEllAR-GROUP / hpx / #855

20 Dec 2022 09:59PM UTC coverage: 86.55% (+0.04%) from 86.511%
#855

push

StellarBot
Merge #6112

6112: Modernize modules from levels 9 and 10 r=hkaiser a=hkaiser

working towards https://github.com/STEllAR-GROUP/hpx/issues/5497

Co-authored-by: Hartmut Kaiser <hartmut.kaiser@gmail.com>

185 of 185 new or added lines in 30 files covered. (100.0%)

174495 of 201611 relevant lines covered (86.55%)

1898061.31 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

75.89
/libs/core/plugin/include/hpx/plugin/plugin_factory.hpp
1
//  Copyright Vladimir Prus 2004.
2
//  Copyright (c) 2005-2014 Hartmut Kaiser
3
//
4
//  SPDX-License-Identifier: BSL-1.0
5
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
6
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7

8
#pragma once
9

10
#include <hpx/config.hpp>
11
#include <hpx/datastructures/any.hpp>
12
#include <hpx/functional/function.hpp>
13
#include <hpx/modules/errors.hpp>
14
#include <hpx/modules/format.hpp>
15
#include <hpx/plugin/abstract_factory.hpp>
16
#include <hpx/plugin/dll.hpp>
17
#include <hpx/plugin/export_plugin.hpp>
18
#include <hpx/plugin/virtual_constructor.hpp>
19

20
#include <algorithm>
21
#include <cctype>
22
#include <sstream>
23
#include <string>
24
#include <type_traits>
25
#include <utility>
26
#include <vector>
27

28
namespace hpx::util::plugin {
29

30
    ///////////////////////////////////////////////////////////////////////////
31
    namespace detail {
32

33
        template <typename BasePlugin, typename DeleterType>
34
        std::pair<abstract_factory<BasePlugin>*, dll_handle>
35
        get_abstract_factory_static(get_plugins_list_type f, DeleterType d,
21,046✔
36
            std::string const& class_name, std::string const& libname = "",
37
            error_code& ec = throws)
38
        {
39
            using PointedType = std::remove_pointer_t<get_plugins_list_type>;
40

41
            exported_plugins_type& e = *f();
21,046✔
42

43
            std::string clsname(class_name);
21,046✔
44
            std::transform(clsname.begin(), clsname.end(), clsname.begin(),
21,046✔
45
                [](char c) { return std::tolower(c); });
451,146✔
46

47
            auto it = e.find(clsname);
21,046✔
48
            if (it != e.end())
21,046✔
49
            {
50
                abstract_factory<BasePlugin>** xw =
21,046✔
51
                    hpx::any_cast<abstract_factory<BasePlugin>*>(&(*it).second);
21,046✔
52

53
                if (!xw)
21,046✔
54
                {
55
                    HPX_THROWS_IF(ec, hpx::error::filesystem_error,
×
56
                        "get_abstract_factory_static",
57
                        "Hpx.Plugin: Can't cast to the right factory type\n");
58
                    return std::pair<abstract_factory<BasePlugin>*,
×
59
                        dll_handle>();
60
                }
61

62
                abstract_factory<BasePlugin>* w = *xw;
21,046✔
63
                return std::make_pair(w, shared_ptr<PointedType>(f, d));
21,046✔
64
            }
65
            else
66
            {
67
                std::ostringstream str;
×
68
                hpx::util::format_to(
×
69
                    str, "Hpx.Plugin: Class '{}' was not found", class_name);
×
70

71
                if (!libname.empty())
×
72
                {
73
                    hpx::util::format_to(
×
74
                        str, " in the shared library '{}'.", libname);
×
75
                }
×
76

77
                if (!e.empty())
×
78
                {
79
                    str << " Existing classes: ";
×
80

81
                    bool first = true;
×
82
                    typename exported_plugins_type::iterator end = e.end();
×
83
                    for (auto jt = e.begin(); jt != end; ++jt)
×
84
                    {
85
                        if (first)
×
86
                        {
87
                            str << "'" << jt->first << "'";
×
88
                            first = false;
×
89
                        }
×
90
                        else
91
                        {
92
                            str << ", '" << jt->first << "'";
×
93
                        }
94
                    }
×
95
                    str << ".";
×
96
                }
×
97
                else
98
                {
99
                    str << " No classes exist.";
×
100
                }
101

102
                HPX_THROWS_IF(ec, hpx::error::filesystem_error,
×
103
                    "get_abstract_factory_static", str.str());
104
                return std::pair<abstract_factory<BasePlugin>*, dll_handle>();
×
105
            }
×
106
        }
21,046✔
107

108
        template <typename BasePlugin>
109
        std::pair<abstract_factory<BasePlugin>*, dll_handle>
110
        get_abstract_factory(dll const& d, std::string const& class_name,
7,598✔
111
            std::string const& base_name, error_code& ec = throws)
112
        {
113
            using DeleterType = hpx::function<void(get_plugins_list_type)>;
114

115
            std::string plugin_entry(HPX_PLUGIN_SYMBOLS_PREFIX_DYNAMIC_STR
7,598✔
116
                "_exported_plugins_list_");
117
            plugin_entry += d.get_mapname();
7,598✔
118
            plugin_entry += "_" + base_name;
7,598✔
119

120
            std::pair<get_plugins_list_type, DeleterType> f =
121
                d.get<get_plugins_list_type, DeleterType>(plugin_entry, ec);
7,598✔
122
            if (ec)
7,598✔
123
                return std::pair<abstract_factory<BasePlugin>*, dll_handle>();
2,934✔
124

125
            return get_abstract_factory_static<BasePlugin>(
4,664✔
126
                f.first, f.second, class_name, d.get_name(), ec);
4,664✔
127
        }
7,598✔
128

129
        ///////////////////////////////////////////////////////////////////////
130
        inline void get_abstract_factory_names_static(get_plugins_list_type f,
3,191✔
131
            std::vector<std::string>& names, error_code& /*ec*/ = throws)
132
        {
133
            exported_plugins_type& e = *f();
3,191✔
134

135
            auto end = e.end();
3,191✔
136
            for (auto it = e.begin(); it != end; ++it)
20,654✔
137
            {
138
                names.push_back((*it).first);
17,463✔
139
            }
17,463✔
140
        }
3,191✔
141

142
        inline void get_abstract_factory_names(dll const& d,
4,688✔
143
            std::string const& base_name, std::vector<std::string>& names,
144
            error_code& ec = throws)
145
        {
146
            using DeleterType = hpx::function<void(get_plugins_list_type)>;
147

148
            std::string plugin_entry(HPX_PLUGIN_SYMBOLS_PREFIX_DYNAMIC_STR
4,688✔
149
                "_exported_plugins_list_");
150
            plugin_entry += d.get_mapname();
4,688✔
151
            plugin_entry += "_" + base_name;
4,688✔
152

153
            std::pair<get_plugins_list_type, DeleterType> f =
154
                d.get<get_plugins_list_type, DeleterType>(plugin_entry, ec);
4,688✔
155
            if (ec)
4,688✔
156
                return;
2,344✔
157

158
            get_abstract_factory_names_static(f.first, names, ec);
2,344✔
159
        }
4,688✔
160

161
        ///////////////////////////////////////////////////////////////////////
162
        struct plugin_factory_item_base
12,290✔
163
        {
164
            plugin_factory_item_base(dll& d, std::string const& basename)
12,290✔
165
              : m_dll(d)
12,290✔
166
              , m_basename(basename)
12,290✔
167
            {
168
            }
12,290✔
169

170
            void create(int******) const;    // dummy placeholder
171

172
            void get_names(
4,688✔
173
                std::vector<std::string>& names, error_code& ec = throws) const
174
            {
175
                get_abstract_factory_names(m_dll, m_basename, names, ec);
4,688✔
176
            }
4,688✔
177

178
        protected:
179
            dll& m_dll;
180
            std::string m_basename;
181
        };
182

183
        ///////////////////////////////////////////////////////////////////////
184
        template <typename BasePlugin, typename Base, typename Parameters>
185
        struct plugin_factory_item;
186

187
        template <typename BasePlugin, typename Base, typename... Parameters>
188
        struct plugin_factory_item<BasePlugin, Base,
12,290✔
189
            hpx::util::pack<Parameters...>> : public Base
190
        {
191
            plugin_factory_item(dll& d, std::string const& basename)
12,290✔
192
              : Base(d, basename)
12,290✔
193
            {
12,290✔
194
            }
12,290✔
195

196
            BasePlugin* create(
197
                std::string const& name, Parameters... parameters) const
198
            {
199
                std::pair<abstract_factory<BasePlugin>*, dll_handle> r =
200
                    get_abstract_factory<BasePlugin>(
201
                        this->m_dll, name, this->m_basename);
202

203
                return r.first->create(r.second, parameters...);
204
            }
205

206
            BasePlugin* create(std::string const& name, error_code& ec,
7,598✔
207
                Parameters... parameters) const
208
            {
209
                std::pair<abstract_factory<BasePlugin>*, dll_handle> r =
210
                    get_abstract_factory<BasePlugin>(
7,598✔
211
                        this->m_dll, name, this->m_basename, ec);
7,598✔
212
                if (ec)
7,598✔
213
                    return nullptr;
2,934✔
214

215
                return r.first->create(r.second, parameters...);
4,664✔
216
            }
7,598✔
217
        };
218

219
        ///////////////////////////////////////////////////////////////////////
220
        // empty deleter for the smart pointer to be used for static
221
        // plugin_factories
222
        inline void empty_deleter(get_plugins_list_type) noexcept {}
16,382✔
223

224
        ///////////////////////////////////////////////////////////////////////
225
        struct static_plugin_factory_item_base
226
        {
227
            explicit static_plugin_factory_item_base(
938✔
228
                get_plugins_list_type const& f_) noexcept
229
              : f(f_)
938✔
230
            {
231
            }
938✔
232

233
            void create(int******) const;    // dummy placeholder
234

235
            void get_names(
847✔
236
                std::vector<std::string>& names, error_code& ec = throws) const
237
            {
238
                get_abstract_factory_names_static(f, names, ec);
847✔
239
            }
847✔
240

241
        protected:
242
            get_plugins_list_type f;
243
        };
244

245
        ///////////////////////////////////////////////////////////////////////
246
        template <typename BasePlugin, typename Base, typename Parameters>
247
        struct static_plugin_factory_item;
248

249
        template <typename BasePlugin, typename Base, typename... Parameters>
250
        struct static_plugin_factory_item<BasePlugin, Base,
251
            hpx::util::pack<Parameters...>> : public Base
252
        {
253
            explicit static_plugin_factory_item(
938✔
254
                get_plugins_list_type const& f) noexcept
255
              : Base(f)
938✔
256
            {
938✔
257
            }
938✔
258

259
            BasePlugin* create(
260
                std::string const& name, Parameters... parameters) const
261
            {
262
                std::pair<abstract_factory<BasePlugin>*, dll_handle> r =
263
                    get_abstract_factory_static<BasePlugin>(
264
                        this->f, &empty_deleter, name, "");
265

266
                return r.first->create(r.second, parameters...);
267
            }
268

269
            BasePlugin* create(std::string const& name, error_code& ec,
16,382✔
270
                Parameters... parameters) const
271
            {
272
                std::pair<abstract_factory<BasePlugin>*, dll_handle> r =
273
                    get_abstract_factory_static<BasePlugin>(
16,382✔
274
                        this->f, &empty_deleter, name, "", ec);
16,382✔
275
                if (ec)
16,382✔
276
                    return nullptr;
×
277

278
                return r.first->create(r.second, parameters...);
16,382✔
279
            }
16,382✔
280
        };
281
    }    // namespace detail
282

283
    ///////////////////////////////////////////////////////////////////////////
284
    template <typename BasePlugin>
285
    struct plugin_factory
12,290✔
286
      : detail::plugin_factory_item<BasePlugin,
287
            detail::plugin_factory_item_base, virtual_constructor_t<BasePlugin>>
288
    {
289
    private:
290
        using base_type = detail::plugin_factory_item<BasePlugin,
291
            detail::plugin_factory_item_base,
292
            virtual_constructor_t<BasePlugin>>;
293

294
    public:
295
        plugin_factory(dll& d, std::string const& basename)
12,290✔
296
          : base_type(d, basename)
12,290✔
297
        {
12,290✔
298
        }
12,290✔
299
    };
300

301
    ///////////////////////////////////////////////////////////////////////////
302
    template <typename BasePlugin>
303
    struct static_plugin_factory
304
      : detail::static_plugin_factory_item<BasePlugin,
305
            detail::static_plugin_factory_item_base,
306
            virtual_constructor_t<BasePlugin>>
307
    {
308
    private:
309
        using base_type = detail::static_plugin_factory_item<BasePlugin,
310
            detail::static_plugin_factory_item_base,
311
            virtual_constructor_t<BasePlugin>>;
312

313
    public:
314
        explicit static_plugin_factory(get_plugins_list_type const& f) noexcept
938✔
315
          : base_type(f)
938✔
316
        {
938✔
317
        }
938✔
318
    };
319
}    // namespace hpx::util::plugin
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc