|
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