Boost logo

Boost-Commit :

From: oryol_at_[hidden]
Date: 2008-08-14 22:54:49


Author: jeremypack
Date: 2008-08-14 22:54:48 EDT (Thu, 14 Aug 2008)
New Revision: 48147
URL: http://svn.boost.org/trac/boost/changeset/48147

Log:
Updates for adaptable_factory: now returns argless function objects
if desired.

Text files modified:
   sandbox/boost/extension/adaptable_factory.hpp | 35 +++++++++++++++++++---
   sandbox/boost/extension/factory.hpp | 16 +++------
   sandbox/boost/extension/impl/adaptable_factory.hpp | 1
   sandbox/boost/extension/impl/adaptable_factory_free_functions.hpp | 44 ++++++++++++++++++++++-----
   sandbox/boost/extension/impl/adaptable_factory_set.hpp | 8 +++-
   sandbox/boost/extension/impl/factory.hpp | 31 +++++++------------
   sandbox/boost/extension/impl/typeinfo.hpp | 37 +++++++++++++++--------
   sandbox/boost/extension/type_map.hpp | 23 +++++++++++---
   sandbox/boost/reflection/constructor_info.hpp | 18 +++++++++-
   sandbox/boost/reflection/impl/reflector_free_functions.hpp | 61 ++++++++++++++++++++++++++++++++++++++++
   sandbox/boost/reflection/parameter.hpp | 54 ++++++++++++++++++++++++++++++----
   sandbox/boost/reflection/parameter_map.hpp | 8 ++--
   12 files changed, 258 insertions(+), 78 deletions(-)

Modified: sandbox/boost/extension/adaptable_factory.hpp
==============================================================================
--- sandbox/boost/extension/adaptable_factory.hpp (original)
+++ sandbox/boost/extension/adaptable_factory.hpp 2008-08-14 22:54:48 EDT (Thu, 14 Aug 2008)
@@ -17,7 +17,10 @@
 #include <string>
 #include <vector>
 
+#include <boost/bind.hpp>
 #include <boost/extension/common.hpp>
+#include <boost/extension/impl/create.hpp>
+#include <boost/function.hpp>
 #include <boost/reflection/parameter_map.hpp>
 
 namespace boost {
@@ -43,7 +46,7 @@
   /** \brief Default constructor.
     * On creation, this adaptable_factory is empty.
     */
- adaptable_factory() : func_(0) {}
+ adaptable_factory() : functor_func_(0), func_(0), check_func_(0) {}
 
   /** \brief Standard copy constructor.
     */
@@ -59,6 +62,7 @@
   /** 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.
+ * Otherwise, it returns NULL.
     * \pre is_valid() == true.
     * \post None.
     */
@@ -66,6 +70,21 @@
     return (*func_)(map, parameter_names_);
   }
 
+ /** Generate a `boost::function` object that can be reused to create
+ * instances of `Interface` based on the data in the _parameter_map_.
+ * If the _parameter_map_ does not contain all of the needed parameters,
+ * then calling `empty()` on the returned function object will return
+ * true.
+ * \return An instance of Interface, if all of the needed parameters are found in map.
+ * Otherwise, it returns NULL.
+ * \pre is_valid() == true.
+ * \post None.
+ */
+ function<Interface* ()> get_function(
+ boost::reflections::parameter_map& map) const {
+ return (*functor_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.
@@ -73,7 +92,7 @@
     * \pre is_valid() == true.
     * \post None.
     */
- std::map<TypeInfo, Info> get_missing_parameter_list(
+ std::vector<std::pair<TypeInfo, Info> > get_missing_params(
       const boost::reflections::parameter_map& map) const {
     return (*check_func_)(map, parameter_names_);
   }
@@ -100,11 +119,15 @@
     * to the constructor for type D.
     * It takes as arguments Info about each parameter
     * in the constructor.
+ * Example:
+ * \code
+ * adaptable_factory<Base, int, int> f;
+ * f.set<Derived>();
+ * \endcode
     * \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...) {}
@@ -114,12 +137,14 @@
   (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:
+ function<Interface* ()> (*functor_func_)(
+ boost::reflections::basic_parameter_map<Info>& map,
+ const std::vector<Info>& names);
   Interface* (*func_)(
     boost::reflections::basic_parameter_map<Info>& map,
     const std::vector<Info>& names);
- std::map<TypeInfo, Info> (*check_func_)(
+ std::vector<std::pair<TypeInfo, Info> > (*check_func_)(
     const boost::reflections::basic_parameter_map<Info>& map,
     const std::vector<Info>& names);
   std::vector<Info> parameter_names_;

Modified: sandbox/boost/extension/factory.hpp
==============================================================================
--- sandbox/boost/extension/factory.hpp (original)
+++ sandbox/boost/extension/factory.hpp 2008-08-14 22:54:48 EDT (Thu, 14 Aug 2008)
@@ -14,6 +14,11 @@
 #define BOOST_EXTENSION_FACTORY_HPP
 
 #include <boost/extension/common.hpp>
+#include <boost/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 {
@@ -86,15 +91,6 @@
 };
 
 #else
-#define N BOOST_EXTENSION_MAX_FUNCTOR_PARAMS
-namespace impl {
-template <class T, class D
- BOOST_PP_COMMA_IF(N)
- BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( \
- BOOST_PP_INC(N), class Param, void) >
-struct create_function;
-} // namespace impl
-#undef N
 
 #define N BOOST_EXTENSION_MAX_FUNCTOR_PARAMS
 
@@ -106,7 +102,7 @@
 
 #undef N
 
-// generate specializations of create_function and factory
+// generate specializations of factory
 # define BOOST_PP_ITERATION_LIMITS \
   (0, BOOST_PP_INC(BOOST_EXTENSION_MAX_FUNCTOR_PARAMS) - 1)
 # define BOOST_PP_FILENAME_1 <boost/extension/impl/factory.hpp>

Modified: sandbox/boost/extension/impl/adaptable_factory.hpp
==============================================================================
--- sandbox/boost/extension/impl/adaptable_factory.hpp (original)
+++ sandbox/boost/extension/impl/adaptable_factory.hpp 2008-08-14 22:54:48 EDT (Thu, 14 Aug 2008)
@@ -28,7 +28,6 @@
           BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N, class Param)>
 static void check_func() {
 
-
 }
 
 

Modified: sandbox/boost/extension/impl/adaptable_factory_free_functions.hpp
==============================================================================
--- sandbox/boost/extension/impl/adaptable_factory_free_functions.hpp (original)
+++ sandbox/boost/extension/impl/adaptable_factory_free_functions.hpp 2008-08-14 22:54:48 EDT (Thu, 14 Aug 2008)
@@ -10,30 +10,56 @@
 // 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,
+ boost::reflections::basic_parameter_map<Info, TypeInfo>& map,
     const std::vector<Info>& names) {
+#if N
+ reflections::generic_parameter<TypeInfo>* gen;
 #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)>();
+ gen = map.template get_first<BOOST_PP_CAT(Param, n)>(names[n]); \
+ if (!gen) return 0; \
+ BOOST_PP_CAT(Param, n) BOOST_PP_CAT(p, n) = \
+ gen->template cast<BOOST_PP_CAT(Param, n)>();
   BOOST_PP_REPEAT(N, BOOST_EXTENSION_GET_FROM_LIST, )
 #undef BOOST_EXTENSION_GET_FROM_LIST
+#endif // N
   return new Derived(BOOST_PP_ENUM_PARAMS(N, p));
 }
 
+template <class Interface, class Derived, class Info, class TypeInfo
+ BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N, class Param)>
+inline boost::function<Interface* ()> get_functor_func(
+ boost::reflections::basic_parameter_map<Info, TypeInfo>& map,
+ const std::vector<Info>& names) {
+#if N
+ reflections::generic_parameter<TypeInfo>* gen;
+#define BOOST_EXTENSION_GET_FROM_LIST(z, n, data) \
+ gen = map.template get_first<BOOST_PP_CAT(Param, n)>(names[n]); \
+ if (!gen) return boost::function<Interface* ()>(); \
+ BOOST_PP_CAT(Param, n) BOOST_PP_CAT(p, n) = \
+ gen->template cast<BOOST_PP_CAT(Param, n)>();
+ BOOST_PP_REPEAT(N, BOOST_EXTENSION_GET_FROM_LIST, )
+#undef BOOST_EXTENSION_GET_FROM_LIST
+#endif // N
+ Interface* (*f)(BOOST_PP_ENUM_PARAMS(N, Param)) =
+ impl::create_derived<Interface, Derived BOOST_PP_COMMA_IF(N)
+ BOOST_PP_ENUM_PARAMS(N, Param)>;
+ return bind(f
+ BOOST_PP_COMMA_IF(N)
+ 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,
+inline std::vector<std::pair<TypeInfo, Info> > check_func(
+ const boost::reflections::basic_parameter_map<Info, TypeInfo>& map,
     const std::vector<Info>& names) {
- std::map<TypeInfo, Info> needed_parameters;
+ std::vector<std::pair<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(\
+ needed_parameters.push_back(std::make_pair(\
     type_info_handler<TypeInfo, \
                       BOOST_PP_CAT(Param, n)>::template get_class_type(), \
     names[n]));

Modified: sandbox/boost/extension/impl/adaptable_factory_set.hpp
==============================================================================
--- sandbox/boost/extension/impl/adaptable_factory_set.hpp (original)
+++ sandbox/boost/extension/impl/adaptable_factory_set.hpp 2008-08-14 22:54:48 EDT (Thu, 14 Aug 2008)
@@ -13,15 +13,19 @@
 template <class Derived
           BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N, class Param)>
 void set(BOOST_PP_ENUM_PARAMS(N, Info i)) {
- parameter_names_.resize(0);
+ parameter_names_.resize(N);
 #define BOOST_EXTENSION_ADD_TO_LIST(z, n, data) \
-parameter_names_.push_back(BOOST_PP_CAT(i, n));
+ parameter_names_[n] = BOOST_PP_CAT(i, n);
   BOOST_PP_REPEAT(N, BOOST_EXTENSION_ADD_TO_LIST, );
 #undef BOOST_EXTENSION_ADD_TO_LIST
   func_ = &impl::create_func
     <Interface, Derived, Info, TypeInfo
      BOOST_PP_COMMA_IF(N)
      BOOST_PP_ENUM_PARAMS(N, Param)>;
+ functor_func_ = &impl::get_functor_func
+ <Interface, Derived, Info, TypeInfo
+ BOOST_PP_COMMA_IF(N)
+ BOOST_PP_ENUM_PARAMS(N, Param)>;
   check_func_ = &impl::check_func
     <Info, TypeInfo BOOST_PP_COMMA_IF(N)
      BOOST_PP_ENUM_PARAMS(N, Param)>;

Modified: sandbox/boost/extension/impl/factory.hpp
==============================================================================
--- sandbox/boost/extension/impl/factory.hpp (original)
+++ sandbox/boost/extension/impl/factory.hpp 2008-08-14 22:54:48 EDT (Thu, 14 Aug 2008)
@@ -11,37 +11,30 @@
 // No header guard - this file is intended to be included multiple times.
 
 # define N BOOST_PP_ITERATION()
-namespace impl {
-template <
- class T,
- class D
- BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N, class Param)
->
-struct create_function<
- T,
- D
- BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N, Param)
-> {
- static T * create(BOOST_PP_ENUM_BINARY_PARAMS(N, Param, p) ) {
- return new D(BOOST_PP_ENUM_PARAMS(N, p));
- }
-};
-} // namespace impl
-
-
 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:
+ // This assertion will fire if a factory type is instantiated
+ // with something that is not a class.
+ BOOST_STATIC_ASSERT((is_class<T>::value));
+ // This assertion will fire if T is const.
+ BOOST_STATIC_ASSERT((!is_const<T>::value));
 
   template <class D>
   void set() {
+ // This assertion will fire if a factory type is
+ // set to a class from which it doesn't inherit.
+ BOOST_STATIC_ASSERT((is_base_of<T, D>::value));
+ // This assertion will fire if D is const.
+ BOOST_STATIC_ASSERT((!is_const<D>::value));
     this->func = &impl::create_function<
         T, D BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N,Param)
>::create;
   }
 
- factory() : func(0) {}
+ factory() : func(0) {
+ }
 
   factory(factory<T> const& first) : func(first.func) {}
 

Modified: sandbox/boost/extension/impl/typeinfo.hpp
==============================================================================
--- sandbox/boost/extension/impl/typeinfo.hpp (original)
+++ sandbox/boost/extension/impl/typeinfo.hpp 2008-08-14 22:54:48 EDT (Thu, 14 Aug 2008)
@@ -22,11 +22,21 @@
 
 class default_type_info {
 public:
- default_type_info(const std::type_info& new_type) : type(new_type) {
+ default_type_info() : type_(&typeid(void)) {
   }
- default_type_info(const default_type_info& first) : type(first.type) {
+ default_type_info(const std::type_info& new_type) : type_(&new_type) {
   }
- const std::type_info& type;
+ default_type_info(const default_type_info& first) : type_(first.type_) {
+ }
+ const std::type_info& type() const {
+ return *type_;
+ }
+ default_type_info& operator=(const default_type_info& first) {
+ type_ = first.type_;
+ return *this;
+ }
+private:
+ const std::type_info* type_;
 };
 template <class ClassType>
 struct type_info_handler<default_type_info, ClassType>
@@ -40,22 +50,23 @@
 
 // This list should be expanded to all platforms that successfully
 // compare type_info across shared library boundaries.
-#if defined(__APPLE__) || defined(__GNUC__) || defined(BOOST_EXTENSION_FORCE_FAST_TYPEINFO)
+#if defined(__APPLE__) || defined(__GNUC__) || \
+ defined(BOOST_EXTENSION_FORCE_FAST_TYPEINFO)
 namespace boost {
 namespace extensions {
 inline bool operator<(const default_type_info& first,
                const default_type_info& second) {
- return &first.type < &second.type;
+ return &first.type() < &second.type();
 }
 
 inline bool operator==(const default_type_info& first,
                const default_type_info& second) {
- return &first.type == &second.type;
+ return &first.type() == &second.type();
 }
 
 inline bool operator>(const default_type_info& first,
                const default_type_info& second) {
- return &first.type > &second.type;
+ return &first.type() > &second.type();
 }
 }}
 #else
@@ -64,17 +75,17 @@
 namespace boost { namespace extensions {
 inline bool operator<(const default_type_info& first,
                const default_type_info& second) {
- return std::strcmp(first.type.raw_name(), second.type.raw_name()) < 0;
+ return std::strcmp(first.type().raw_name(), second.type().raw_name()) < 0;
 }
 
 inline bool operator==(const default_type_info& first,
                const default_type_info& second) {
- return std::strcmp(first.type.raw_name(), second.type.raw_name()) == 0;
+ return std::strcmp(first.type().raw_name(), second.type().raw_name()) == 0;
 }
 
 inline bool operator>(const default_type_info& first,
                const default_type_info& second) {
- return std::strcmp(first.type.raw_name(), second.type.raw_name()) > 0;
+ return std::strcmp(first.type().raw_name(), second.type().raw_name()) > 0;
 }
 } // namespace extensions
 } // namespace boost
@@ -83,17 +94,17 @@
 namespace boost { namespace extensions {
 inline bool operator<(const default_type_info& first,
                const default_type_info& second) {
- return std::strcmp(first.type.name(), second.type.name()) < 0;
+ return std::strcmp(first.type().name(), second.type().name()) < 0;
 }
 
 inline bool operator==(const default_type_info& first,
                const default_type_info& second) {
- return std::strcmp(first.type.name(), second.type.name()) == 0;
+ return std::strcmp(first.type().name(), second.type().name()) == 0;
 }
 
 inline bool operator>(const default_type_info& first,
                const default_type_info& second) {
- return std::strcmp(first.type.name(), second.type.name()) > 0;
+ return std::strcmp(first.type().name(), second.type().name()) > 0;
 }
 } // namespace extensions
 } // namespace boost

Modified: sandbox/boost/extension/type_map.hpp
==============================================================================
--- sandbox/boost/extension/type_map.hpp (original)
+++ sandbox/boost/extension/type_map.hpp 2008-08-14 22:54:48 EDT (Thu, 14 Aug 2008)
@@ -15,6 +15,10 @@
 
 #include <map>
 #include <boost/extension/impl/typeinfo.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/has_nothrow_assign.hpp>
+#include <boost/type_traits/has_nothrow_copy_constructor.hpp>
 
 namespace boost {
 namespace extensions {
@@ -47,6 +51,10 @@
 template <class TypeInfo>
 class basic_type_map {
 public:
+// Some assertions about the TypeInfo type.
+ BOOST_STATIC_ASSERT(has_nothrow_assign<TypeInfo>::value);
+ BOOST_STATIC_ASSERT(has_nothrow_copy_constructor<TypeInfo>::value);
+
 #ifndef BOOST_EXTENSION_DOXYGEN_INVOKED
   class type_map_convertible {
   public:
@@ -58,25 +66,30 @@
     }
     template <class Type>
     operator Type&() {
- TypeInfo t = type_info_handler<TypeInfo, Type>::get_class_type();
-
+ typedef typename remove_const<Type>::type StoredType;
+ TypeInfo t =
+ type_info_handler<TypeInfo, StoredType>
+ ::get_class_type();
       typename std::map<TypeInfo, generic_type_holder*>::iterator
         it = instances_.find(t);
   
- type_holder<Type>* holder;
+ type_holder<StoredType>* holder;
       if (it == instances_.end()) {
- holder = new type_holder<Type>;
+ holder = new type_holder<StoredType>;
         it = instances_.insert(std::make_pair(t, holder)).first;
       }
       else {
- holder = static_cast<type_holder<Type>* > (it->second);
+ holder = static_cast<type_holder<StoredType>*>(it->second);
       }
       return holder->val;
     }
+
   private:
     struct generic_type_holder {
       virtual ~generic_type_holder() {}
     };
+
+ // T must be default constructible.
     template <class T>
     struct type_holder : generic_type_holder {
       T val;

Modified: sandbox/boost/reflection/constructor_info.hpp
==============================================================================
--- sandbox/boost/reflection/constructor_info.hpp (original)
+++ sandbox/boost/reflection/constructor_info.hpp 2008-08-14 22:54:48 EDT (Thu, 14 Aug 2008)
@@ -17,14 +17,26 @@
   * those without.
   */
 #ifdef BOOST_REFLECTION_WITH_PARAMETER_INFO
-template<class TypeInfo, class ParameterInfo = void>
+template<class TypeInfo, class Info = void>
 struct basic_constructor_info {
 /** A description for each parameter of the function.
- * If ParameterInfo=void, this does not appear.
+ * If Info=void, this does not appear.
   * This member variable only occurs for reflections with
   * parameter info.
   */
- std::vector<ParameterInfo> parameter_info_;
+ std::vector<Info> parameter_info_;
+ private:
+ function<instance ()> (*functor_func_)(
+ boost::reflections::basic_parameter_map<Info>& map,
+ const std::vector<Info>& names);
+ instance (*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_;
+ public:
 #else
 template<class TypeInfo>
 struct basic_constructor_info<TypeInfo> {

Modified: sandbox/boost/reflection/impl/reflector_free_functions.hpp
==============================================================================
--- sandbox/boost/reflection/impl/reflector_free_functions.hpp (original)
+++ sandbox/boost/reflection/impl/reflector_free_functions.hpp 2008-08-14 22:54:48 EDT (Thu, 14 Aug 2008)
@@ -45,4 +45,65 @@
   // Call the function and return the result.
   return (actual->*func)(BOOST_PP_ENUM_PARAMS(N, p));
 }
+
+// The following are versions of the above that don't require
+// knowing their parameters.
+
+template <class Derived, class Info, class TypeInfo
+ BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N, class Param)>
+instance create_func(
+ boost::reflections::basic_parameter_map<Info, TypeInfo>& map,
+ const std::vector<Info>& names) {
+#if N
+ reflections::generic_parameter<TypeInfo>* gen;
+#define BOOST_REFLECTION_GET_FROM_LIST(z, n, data) \
+ gen = map.template get_first<BOOST_PP_CAT(Param, n)>(names[n]); \
+ if (!gen) return 0; \
+ BOOST_PP_CAT(Param, n) BOOST_PP_CAT(p, n) = \
+ gen->template cast<BOOST_PP_CAT(Param, n)>();
+ BOOST_PP_REPEAT(N, BOOST_REFLECTION_GET_FROM_LIST, )
+#undef BOOST_REFLECTION_GET_FROM_LIST
+#endif // N
+ return new Derived(BOOST_PP_ENUM_PARAMS(N, p));
+}
+
+template <class Interface, class Derived, class Info, class TypeInfo
+ BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N, class Param)>
+boost::function<instance ()> get_functor_func(
+ boost::reflections::basic_parameter_map<Info, TypeInfo>& map,
+ const std::vector<Info>& names) {
+#if N
+ reflections::generic_parameter<TypeInfo>* gen;
+#define BOOST_REFLECTION_GET_FROM_LIST(z, n, data) \
+ gen = map.template get_first<BOOST_PP_CAT(Param, n)>(names[n]); \
+ if (!gen) return boost::function<Interface* ()>(); \
+ BOOST_PP_CAT(Param, n) BOOST_PP_CAT(p, n) = \
+ gen->template cast<BOOST_PP_CAT(Param, n)>();
+ BOOST_PP_REPEAT(N, BOOST_REFLECTION_GET_FROM_LIST, )
+#undef BOOST_REFLECTION_GET_FROM_LIST
+#endif // N
+ Interface* (*f)(BOOST_PP_ENUM_PARAMS(N, Param)) =
+ impl::create_derived<Interface, Derived BOOST_PP_COMMA_IF(N)
+ BOOST_PP_ENUM_PARAMS(N, Param)>;
+ return bind(f
+ BOOST_PP_COMMA_IF(N)
+ 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, TypeInfo>& map,
+ const std::vector<Info>& names) {
+ std::map<TypeInfo, Info> needed_parameters;
+#define BOOST_REFLECTION_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_REFLECTION_CHECK_IN_LIST, )
+#undef BOOST_REFLECTION_CHECK_IN_LIST
+ return needed_parameters;
+}
 #undef N

Modified: sandbox/boost/reflection/parameter.hpp
==============================================================================
--- sandbox/boost/reflection/parameter.hpp (original)
+++ sandbox/boost/reflection/parameter.hpp 2008-08-14 22:54:48 EDT (Thu, 14 Aug 2008)
@@ -25,10 +25,22 @@
     return "Cannot convert types";
   }
 };
+/** \brief A container for a single item - similar to boost::any.
+ *
+ * The primary difference between generic_parameter and boost::any
+ * is that a generic_parameter can be declared to be convertible
+ * to arbitrary types, in addition to the base type that it holds.
+ * This allows an object to also be accessible through pointers to
+ * its base types, for example.
+ */
 template <class TypeInfo = extensions::default_type_info>
 class generic_parameter {
 public:
   typedef void (*FunctionPtr)();
+
+ /** The destructor cleans up the converters contained
+ * in this generic_parameter.
+ */
   virtual ~generic_parameter() {
     for (typename std::map<TypeInfo, basic_converter*>::iterator
          it = converters_.begin();
@@ -36,16 +48,38 @@
       delete it->second;
     }
   }
+
+ /** Return the TypeInfo for the primary type of this generic_parameter.
+ */
   virtual TypeInfo type() const = 0;
+
+ /** \brief Returns true if the parameter can convert to T.
+ *
+ * Given a type T, this function returns true if the generic_parameter
+ * can convert its value to T.
+ * \tparam T The type to check for conversions for.
+ * \returns true if the conversion is possible.
+ */
   template <class T>
   bool can_cast() const {
     TypeInfo i = type_info_handler<TypeInfo, T>::get_class_type();
     return (converters_.find(i) != converters_.end());
   }
- template <class S>
- S cast() const {
- S dest;
- TypeInfo i = type_info_handler<TypeInfo, S>::get_class_type();
+
+ /** \brief Returns a type S, converted from the type in the parameter.
+ *
+ * This will attempt to convert the generic_parameter to type T.
+ * If it fails, it will throw an exception. To avoid the exception,
+ * the can_cast function can be called first.
+ * \tparam T
+ * \returns A value of T that was converted from the generic_parameter.
+ * \pre can_cast<T>() == true
+ * \post None.
+ */
+ template <class T>
+ T cast() const {
+ T dest;
+ TypeInfo i = type_info_handler<TypeInfo, T>::get_class_type();
     typename std::map<TypeInfo, basic_converter*>::const_iterator it =
       converters_.find(i);
     if (it != converters_.end()) {
@@ -54,9 +88,14 @@
     }
     throw conversion_not_found_exception();
   }
- template <class S>
- void cast(S* dest) {
- *dest = cast<S>();
+
+ /** \brief Another form of cast.
+ *
+ * Identical to T cast(), but takes a pointer to T instead.
+ */
+ template <class T>
+ void cast(T* dest) {
+ *dest = cast<T>();
   }
 protected:
   generic_parameter(void* value) : value_(value) {
@@ -80,6 +119,7 @@
   virtual TypeInfo type() const {
     return reflections::type_info_handler<TypeInfo, T>::get_class_type();
   }
+
   explicit parameter(T value)
     : generic_parameter<TypeInfo>(reinterpret_cast<void*>(&value_)),
       value_(value) {

Modified: sandbox/boost/reflection/parameter_map.hpp
==============================================================================
--- sandbox/boost/reflection/parameter_map.hpp (original)
+++ sandbox/boost/reflection/parameter_map.hpp 2008-08-14 22:54:48 EDT (Thu, 14 Aug 2008)
@@ -56,7 +56,7 @@
     * \tparam D The type of parameter to return.
     */
   template <class D>
- std::vector<generic_parameter<TypeInfo>*> get(Info info) {
+ std::vector<generic_parameter<TypeInfo>*> get(const Info& info) {
     std::vector<generic_parameter<TypeInfo>*> parameters;
     std::pair<typename map_type::iterator, typename map_type::iterator> its
       = equal_range(info);
@@ -82,7 +82,7 @@
     * \tparam D The type of parameter to search for.
     */
   template <class D>
- bool has(Info info) const {
+ bool has(const Info& info) const {
     std::pair<typename map_type::const_iterator,
               typename map_type::const_iterator> its
       = equal_range(info);
@@ -109,7 +109,7 @@
     * \tparam D The type of parameter to search for.
     */
   template <class D>
- generic_parameter<TypeInfo>* get_first(Info info) {
+ generic_parameter<TypeInfo>* get_first(const Info& info) {
     std::pair<typename map_type::iterator, typename map_type::iterator> its
       = equal_range(info);
     for (typename map_type::iterator current = its.first;
@@ -119,7 +119,7 @@
         return &p;
       }
     }
- throw parameter_unavailable_exception();
+ return 0;
   }
 };
 typedef basic_parameter_map<> parameter_map;


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