|
Boost-Commit : |
From: oryol_at_[hidden]
Date: 2008-07-19 22:24:25
Author: jeremypack
Date: 2008-07-19 22:24:24 EDT (Sat, 19 Jul 2008)
New Revision: 47612
URL: http://svn.boost.org/trac/boost/changeset/47612
Log:
Add adaptable_factory type.
Added:
sandbox/boost/extension/adaptable_factory.hpp (contents, props changed)
sandbox/boost/extension/impl/adaptable_factory.hpp (contents, props changed)
sandbox/boost/extension/impl/adaptable_factory_free_functions.hpp (contents, props changed)
Text files modified:
sandbox/boost/extension/factory_map.hpp | 28 ++++++++++++++++++++++++++++
sandbox/boost/extension/impl/factory_map.hpp | 4 +---
sandbox/boost/extension/impl/typeinfo.hpp | 2 ++
sandbox/boost/extension/shared_library.hpp | 8 +++++---
4 files changed, 36 insertions(+), 6 deletions(-)
Added: sandbox/boost/extension/adaptable_factory.hpp
==============================================================================
--- (empty file)
+++ sandbox/boost/extension/adaptable_factory.hpp 2008-07-19 22:24:24 EDT (Sat, 19 Jul 2008)
@@ -0,0 +1,131 @@
+/*
+ * Boost.Extension / adaptable_factory:
+ * factory to register the implementations and create them,
+ * without binding the parameter types into the factory type.
+ *
+ * (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_ADAPTABLE_FACTORY_HPP
+#define BOOST_EXTENSION_ADAPTABLE_FACTORY_HPP
+
+#include <string>
+#include <vector>
+
+#include <boost/extension/common.hpp>
+#include <boost/reflection/parameter_map.hpp>
+
+namespace boost {
+namespace extensions {
+namespace impl {
+#ifndef BOOST_EXTENSION_DOXYGEN_INVOKED
+# define BOOST_PP_ITERATION_LIMITS \
+ (0, BOOST_PP_INC(BOOST_EXTENSION_MAX_FUNCTOR_PARAMS) - 1)
+# define BOOST_PP_FILENAME_1 <boost/extension/impl/adaptable_factory_free_functions.hpp>
+# include BOOST_PP_ITERATE()
+#endif // BOOST_EXTENSION_DOXYGEN_INVOKED
+} // namespace impl
+
+/** This class is a function object that returns
+ * new instances of type Interface, using factories that
+ * take parameters described in the variable length
+ * list Params...
+ */
+template <class Interface, class Info = std::string,
+ class TypeInfo = default_type_info>
+class adaptable_factory {
+public:
+ /** \brief Default constructor.
+ * On creation, this adaptable_factory is empty.
+ */
+ adaptable_factory() : func_(0) {}
+
+ /** \brief Standard copy constructor.
+ */
+ adaptable_factory(adaptable_factory<Interface> const& first) : func_(first.func_) {}
+
+ /** \brief Standard assignment operator.
+ */
+ adaptable_factory& operator=(adaptable_factory<Interface> const& first) {
+ this->func_ = first->func_;
+ return *this;
+ }
+
+ /** Returns an instance of Interface (but does NOT retain ownership of the instance).
+ * \param map A parameter map to search for the parameters for this function.
+ * \return An instance of Interface, if all of the needed parameters are found in map.
+ * \pre is_valid() == true.
+ * \post None.
+ */
+ Interface* create(boost::reflections::parameter_map& map) const {
+ return (*func_)(map, parameter_names_);
+ }
+
+ /** Returns a map of the TypeInfo/Info pairs describing any parameters still
+ * needed before this function can be called.
+ * \param map A parameter map to search for the parameters for this function.
+ * \return TypeInfo/Info pairs for any missing parameters.
+ * \pre is_valid() == true.
+ * \post None.
+ */
+ std::map<TypeInfo, Info> get_missing_parameter_list(
+ const boost::reflections::parameter_map& map) const {
+ return (*check_func_)(map, parameter_names_);
+ }
+
+ /** \brief Returns true if set has been called.
+ *
+ * Until set is called, a adaptable_factory cannot be used. This
+ * function can be used to determine if set has been called.
+ * \pre None.
+ * \post None.
+ * \return True if the adaptable_factory is initialized (ie, set has been called).
+ */
+ bool is_valid() const { return this->func_ != 0; }
+
+/* For Doxygen, and for easier readability by users, a
+ * simplified version of this class's set function is provided, but never
+ * compiled.
+ */
+#ifdef BOOST_EXTENSION_DOXYGEN_INVOKED
+
+ /** \brief Set the factory function for this adaptable_factory.
+ *
+ * This sets the factory function
+ * to the constructor for type D.
+ * It takes as arguments Info about each parameter
+ * in the constructor.
+ * \param parameter_names A variable length list of Info
+ * to describe the parameters of the constructor.
+ * \pre None.
+ * \post None.
+ * Example: adaptable_factory<Base, int, int> f; f.set<Derived>();
+ */
+ template <class Derived, class Params...>
+ void set(Info parameter_names...) {}
+#else
+
+# define BOOST_PP_ITERATION_LIMITS \
+ (0, BOOST_PP_INC(BOOST_EXTENSION_MAX_FUNCTOR_PARAMS) - 1)
+# define BOOST_PP_FILENAME_1 <boost/extension/impl/adaptable_factory_set.hpp>
+# include BOOST_PP_ITERATE()
+
+private:
+ Interface* (*func_)(
+ boost::reflections::basic_parameter_map<Info>& map,
+ const std::vector<Info>& names);
+ std::map<TypeInfo, Info> (*check_func_)(
+ const boost::reflections::basic_parameter_map<Info>& map,
+ const std::vector<Info>& names);
+ std::vector<Info> parameter_names_;
+#endif // BOOST_EXTENSION_DOXYGEN_INVOKED
+};
+} // namespace extensions
+} // namespace boost
+
+#endif // BOOST_EXTENSION_FACTORY_HPP
Modified: sandbox/boost/extension/factory_map.hpp
==============================================================================
--- sandbox/boost/extension/factory_map.hpp (original)
+++ sandbox/boost/extension/factory_map.hpp 2008-07-19 22:24:24 EDT (Sat, 19 Jul 2008)
@@ -14,6 +14,7 @@
#define BOOST_EXTENSION_FACTORY_MAP_HPP
#include <map>
+#include <boost/extension/adaptable_factory.hpp>
#include <boost/extension/factory.hpp>
#include <boost/extension/impl/typeinfo.hpp>
@@ -34,6 +35,33 @@
delete it->second;
}
}
+
+
+ template <class Interface, class Info, class AdaptableInfo>
+ std::map<
+ Info,
+ adaptable_factory<Interface, AdaptableInfo, TypeInfo> >&
+ get_adaptable() {
+ TypeInfo t = adaptable_factory<Interface>::get_class_type();
+
+ typename std::map<TypeInfo, generic_map_holder*>::iterator
+ it = maps_.find(t);
+
+ typedef adaptable_factory<
+ Interface, AdaptableInfo, TypeInfo
+ > factory_type;
+ typedef std::map<Info, factory_type> map_type;
+
+ map_holder<map_type>* holder;
+ if (it == maps_.end()) {
+ holder = new map_holder<map_type>;
+ it = maps_.insert(std::make_pair(t, holder)).first;
+ }
+ else {
+ holder = static_cast<map_holder<map_type>* > (it->second);
+ }
+ return *(static_cast<map_type*>(holder));
+ }
/* Include simplified versions of the get and conversion member
* functions for Doxygen, and to make it easier for readers of
* this file.
Added: sandbox/boost/extension/impl/adaptable_factory.hpp
==============================================================================
--- (empty file)
+++ sandbox/boost/extension/impl/adaptable_factory.hpp 2008-07-19 22:24:24 EDT (Sat, 19 Jul 2008)
@@ -0,0 +1,73 @@
+/*
+ * Copyright Jeremy Pack 2007
+ * 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.
+ */
+
+
+// No header guard - this file is intended to be included multiple times.
+
+# define N BOOST_PP_ITERATION()
+
+public:
+template <class Interface, class Derived
+ BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N, class Param)>
+
+private:
+template <class Interface, class Derived
+ BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N, class Param)>
+static Interface* create_func() {
+
+
+}
+
+template <class Interface, class Derived
+ BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N, class Param)>
+static void check_func() {
+
+
+}
+
+
+template <class T BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N, class Param) >
+class factory<T BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N, Param) >
+{
+public:
+
+ template <class D>
+ void set() {
+ this->func = &impl::create_function<
+ T, D BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N,Param)
+ >::create;
+ }
+
+ factory() : func(0) {}
+
+ factory(factory<T> const& first) : func(first.func) {}
+
+ factory& operator=(factory<T> const& first) {
+ this->func = first->func;
+ return *this;
+ }
+
+ bool is_valid() const { return this->func != 0; }
+
+ T* create(BOOST_PP_ENUM_BINARY_PARAMS(N, Param, p)) const {
+ if (this->func) {
+ return this->func(BOOST_PP_ENUM_PARAMS(N, p));
+ }
+ else {
+ return 0;
+ }
+ }
+
+private:
+ typedef T* (*func_ptr_type)(BOOST_PP_ENUM_PARAMS(N, Param));
+ func_ptr_type func;
+};
+
+#undef N
+
Added: sandbox/boost/extension/impl/adaptable_factory_free_functions.hpp
==============================================================================
--- (empty file)
+++ sandbox/boost/extension/impl/adaptable_factory_free_functions.hpp 2008-07-19 22:24:24 EDT (Sat, 19 Jul 2008)
@@ -0,0 +1,45 @@
+/*
+ * Copyright Jeremy Pack 2007
+ * 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.
+ */
+
+// No header guard - this file is intended to be included multiple times.
+
+#define N BOOST_PP_ITERATION()
+
+template <class Interface, class Derived, class Info, class TypeInfo
+ BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N, class Param)>
+inline Interface* create_func(
+ boost::reflections::basic_parameter_map<Info>& map,
+ const std::vector<Info>& names) {
+#define BOOST_EXTENSION_GET_FROM_LIST(z, n, data) \
+BOOST_PP_CAT(Param, n) BOOST_PP_CAT(p, n) = \
+ map.template get_first<BOOST_PP_CAT(Param, n)>(names[n]) \
+ ->template cast<BOOST_PP_CAT(Param, n)>();
+ BOOST_PP_REPEAT(N, BOOST_EXTENSION_GET_FROM_LIST, )
+#undef BOOST_EXTENSION_GET_FROM_LIST
+ return new Derived(BOOST_PP_ENUM_PARAMS(N, p));
+}
+
+template <class Info, class TypeInfo BOOST_PP_COMMA_IF(N)
+ BOOST_PP_ENUM_PARAMS(N, class Param)>
+inline std::map<TypeInfo, Info> check_func(
+ const boost::reflections::basic_parameter_map<Info>& map,
+ const std::vector<Info>& names) {
+ std::map<TypeInfo, Info> needed_parameters;
+#define BOOST_EXTENSION_CHECK_IN_LIST(z, n, data) \
+if (!map.template has<BOOST_PP_CAT(Param, n)>(names[n])) \
+ needed_parameters.insert(std::make_pair(\
+ type_info_handler<TypeInfo, \
+ BOOST_PP_CAT(Param, n)>::template get_class_type(), \
+ names[n]));
+ BOOST_PP_REPEAT(N, BOOST_EXTENSION_CHECK_IN_LIST, )
+#undef BOOST_EXTENSION_CHECK_IN_LIST
+ return needed_parameters;
+}
+#undef N
+
Modified: sandbox/boost/extension/impl/factory_map.hpp
==============================================================================
--- sandbox/boost/extension/impl/factory_map.hpp (original)
+++ sandbox/boost/extension/impl/factory_map.hpp 2008-07-19 22:24:24 EDT (Sat, 19 Jul 2008)
@@ -39,15 +39,13 @@
holder = new map_holder<map_type>;
it = maps_.insert(std::make_pair(t, holder)).first;
}
- else
- {
+ else {
holder = static_cast<map_holder<map_type>* > (it->second);
}
return *(static_cast<map_type* >(holder));
}
-
template <class Interface, class Info
BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N, class Param) >
operator
Modified: sandbox/boost/extension/impl/typeinfo.hpp
==============================================================================
--- sandbox/boost/extension/impl/typeinfo.hpp (original)
+++ sandbox/boost/extension/impl/typeinfo.hpp 2008-07-19 22:24:24 EDT (Sat, 19 Jul 2008)
@@ -24,6 +24,8 @@
public:
default_type_info(const std::type_info& new_type) : type(new_type) {
}
+ default_type_info(const default_type_info& first) : type(first.type) {
+ }
const std::type_info& type;
};
template <class ClassType>
Modified: sandbox/boost/extension/shared_library.hpp
==============================================================================
--- sandbox/boost/extension/shared_library.hpp (original)
+++ sandbox/boost/extension/shared_library.hpp 2008-07-19 22:24:24 EDT (Sat, 19 Jul 2008)
@@ -11,6 +11,7 @@
* See http://www.boost.org/ for latest version.
*/
+
#ifndef BOOST_EXTENSION_SHARED_LIBRARY_HPP
#define BOOST_EXTENSION_SHARED_LIBRARY_HPP
@@ -24,9 +25,10 @@
namespace extensions {
/** \brief A wrapper around OS-specific shared library functions.
- * \warning This class is inherently not type-safe. Carefully
- * check the signature of the function or type in the shared library
- * against the template arguments of the get functions.
+
+\note This class is inherently not type-safe. Carefully
+check the signature of the function or type in the shared library
+against the template arguments of the get functions.
*/
class shared_library {
public:
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk