-
Notifications
You must be signed in to change notification settings - Fork 298
/
factory.hpp
114 lines (100 loc) · 3.14 KB
/
factory.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
* Boost.Extension / factory:
* factory to register the implementations and create them
*
* (C) Copyright Jeremy Pack 2008
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/ for latest version.
*/
#ifndef BOOST_EXTENSION_FACTORY_HPP
#define BOOST_EXTENSION_FACTORY_HPP
#include <Core/Utils/extension/common.hpp>
#include <Core/Utils/extension/impl/create.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/type_traits/is_class.hpp>
#include <boost/type_traits/is_const.hpp>
namespace boost {
namespace extensions {
/* For Doxygen, and for easier readability by users, a
* simplified version of this class is provided, but never
* compiled. The actual class definition is in impl/factory.hpp.
*/
#ifdef BOOST_EXTENSION_DOXYGEN_INVOKED
/** This class is a function object that returns
* new instances of type T, using factories that
* take parameters described in the variable length
* list Params...
*/
template <class T, class Params... >
class factory {
public:
/** \brief Set the factory function for this factory.
*
* This sets the factory function
* to the constructor for type D.
* Example: factory<Base, int, int> f; f.set<Derived>();
*/
template <class D>
void set() {
this->func = &impl::create_function<
T, D BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N,Param)
>::create;
}
/** \brief Default constructor.
* On creation, this factory is empty.
*/
factory() : func(0) {}
/** \brief Standard copy constructor.
*/
factory(factory<T> const& first) : func(first.func) {}
/** \brief Standard assignment operator.
*/
factory& operator=(factory<T> const& first) {
this->func = first->func;
return *this;
}
/** \brief Returns true if set has been called.
*
* Until set is called, a factory cannot be used. This
* function can be used to determine if set has been called.
* \pre None.
* \post None.
* \return True if the factory is initialized (ie, set has been called).
*/
bool is_valid() const { return this->func != 0; }
/** Returns an instance of T (but does NOT retain ownership of the instance).
* \param Params... The parameters described in the type of this factory.
* \return An instance of T.
* \pre is_valid() == true.
* \post None.
*/
T* create(Params...) const {
if (this->func) {
return this->func(BOOST_PP_ENUM_PARAMS(N, p));
}
else {
return 0;
}
}
};
#else
#define N BOOST_EXTENSION_MAX_FUNCTOR_PARAMS
template <class T
BOOST_PP_COMMA_IF(N)
BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
BOOST_PP_INC(N), class Param, void) >
class factory;
#undef N
// generate specializations of factory
# define BOOST_PP_ITERATION_LIMITS \
(0, BOOST_PP_INC(BOOST_EXTENSION_MAX_FUNCTOR_PARAMS) - 1)
# define BOOST_PP_FILENAME_1 "Core/Utils/extension/impl/factory.hpp"
# include BOOST_PP_ITERATE()
#endif
} // namespace extensions
} // namespace boost
#endif // BOOST_EXTENSION_FACTORY_HPP