$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r50282 - in sandbox/mirror: boost/mirror libs/mirror/example libs/mirror/example/factories
From: chochlik_at_[hidden]
Date: 2008-12-15 15:27:37
Author: matus.chochlik
Date: 2008-12-15 15:27:36 EST (Mon, 15 Dec 2008)
New Revision: 50282
URL: http://svn.boost.org/trac/boost/changeset/50282
Log:
[mirror 0.3.x]
- Added an example using the configurable generic factory
Added:
   sandbox/mirror/libs/mirror/example/factories/
   sandbox/mirror/libs/mirror/example/factories/tetrahedron.cpp   (contents, props changed)
Text files modified: 
   sandbox/mirror/boost/mirror/factory.hpp           |     1 +                                       
   sandbox/mirror/boost/mirror/meta_constructors.hpp |     7 ++++++-                                 
   sandbox/mirror/libs/mirror/example/Jamfile.v2     |     4 ++++                                    
   3 files changed, 11 insertions(+), 1 deletions(-)
Modified: sandbox/mirror/boost/mirror/factory.hpp
==============================================================================
--- sandbox/mirror/boost/mirror/factory.hpp	(original)
+++ sandbox/mirror/boost/mirror/factory.hpp	2008-12-15 15:27:36 EST (Mon, 15 Dec 2008)
@@ -13,6 +13,7 @@
 
 #include <boost/mirror/meta_constructors.hpp>
 #include <boost/mpl/accumulate.hpp>
+#include <boost/mpl/push_back.hpp>
 #include <boost/mirror/detail/argument_type_list.hpp>
 
 
Modified: sandbox/mirror/boost/mirror/meta_constructors.hpp
==============================================================================
--- sandbox/mirror/boost/mirror/meta_constructors.hpp	(original)
+++ sandbox/mirror/boost/mirror/meta_constructors.hpp	2008-12-15 15:27:36 EST (Mon, 15 Dec 2008)
@@ -12,6 +12,9 @@
 
 #include <boost/mpl/vector.hpp>
 #include <boost/mpl/size.hpp>
+#include <boost/mpl/accumulate.hpp>
+#include <boost/mpl/push_back.hpp>
+
 #include <boost/preprocessor/repetition/enum.hpp>
 #include <boost/preprocessor/repetition/repeat.hpp>
 #include <boost/preprocessor/seq/size.hpp>
@@ -23,6 +26,9 @@
 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
 #include <boost/preprocessor/repetition/enum_params.hpp>
 #include <boost/preprocessor/facilities/empty.hpp>
+#include <boost/preprocessor/stringize.hpp>
+#include <boost/preprocessor/wstringize.hpp>
+
 
 namespace boost {
 namespace mirror {
@@ -127,7 +133,6 @@
         BOOST_MIRROR_REG_CONSTRUCTOR(1, ((TYPE)(init))) \
 BOOST_MIRROR_REG_CONSTRUCTORS_END 
 
-BOOST_MIRROR_REGISTER_NATIVE_TYPE_CONSTRUCTORS(void)
 BOOST_MIRROR_REGISTER_NATIVE_TYPE_CONSTRUCTORS(bool)
 BOOST_MIRROR_REGISTER_NATIVE_TYPE_CONSTRUCTORS(char)
 BOOST_MIRROR_REGISTER_NATIVE_TYPE_CONSTRUCTORS(unsigned char)
Modified: sandbox/mirror/libs/mirror/example/Jamfile.v2
==============================================================================
--- sandbox/mirror/libs/mirror/example/Jamfile.v2	(original)
+++ sandbox/mirror/libs/mirror/example/Jamfile.v2	2008-12-15 15:27:36 EST (Mon, 15 Dec 2008)
@@ -35,6 +35,10 @@
 exe tvrsl_sample_visitor       : traversal/sample_visitor.cpp ;
 exe tvrsl_meta_path_visitor    : traversal/sample_meta_path.cpp ;
 #
+# configurable factories
+#
+exe fctry_tetrahedron		: factories/tetrahedron.cpp ;
+#
 # cooperation with Boost.Serialization
 #
 #exe serial_cube       : serialization/cube.cpp ;
Added: sandbox/mirror/libs/mirror/example/factories/tetrahedron.cpp
==============================================================================
--- (empty file)
+++ sandbox/mirror/libs/mirror/example/factories/tetrahedron.cpp	2008-12-15 15:27:36 EST (Mon, 15 Dec 2008)
@@ -0,0 +1,264 @@
+/**
+ * \file examples/factories/tetrahedron.cpp
+ *
+ *  This example shows how to use the configurable factory
+ *  with a input user interface implementation to generically 
+ *  construct an instance of classes with non default constructors.
+ *
+ *  Copyright 2008 Matus Chochlik. 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)
+ */
+
+#include <math.h>
+#include <cstdlib>
+
+#include <boost/char_type_switch/iostream.hpp>
+#include <boost/mirror/factory.hpp>
+#include <boost/mirror/meta_type.hpp>
+
+namespace test {
+	
+struct vector
+{
+	double x,y,z;
+
+	vector(double _x, double _y, double _z)
+	 : x(_x)
+	 , y(_y)
+	 , z(_z)
+	{ }
+
+	vector(void)
+	 : x(0.0)
+	 , y(0.0)
+	 , z(0.0)
+	{ }
+
+	friend vector operator + (const vector& a, const vector& b)
+	{
+		return vector(a.x + b.x, a.y + b.y, a.z + b.z);
+	}
+
+	friend vector operator - (const vector& a, const vector& b)
+	{
+		return vector(a.x - b.x, a.y - b.y, a.z - b.z);
+	}
+
+	// cross product
+	friend vector operator % (const vector& a, const vector& b)
+	{
+		return vector(
+			a.y * b.z - a.z * b.y,
+			a.z * b.x - a.x * b.z,
+			a.x * b.y - a.y * b.x
+		);
+	}
+
+	// dot product
+	friend double operator * (const vector& a, const vector& b)
+	{
+		return a.x*b.x + a.y*b.y + a.z*b.z;
+	}
+
+	double length(void) const
+	{
+		return sqrt(x*x + y*y + z*z);
+	}
+};
+
+struct triangle
+{
+	vector a, b, c;
+
+	triangle(const vector& _a, const vector& _b, const vector& _c)
+	 : a(_a)
+	 , b(_b)
+	 , c(_c)
+	{ }
+
+
+	double area(void) const 
+	{
+		return ((b-a)%(c-a)).length()/2.0;
+	}
+};
+
+struct tetrahedron
+{
+	triangle base;
+	vector apex;
+
+	tetrahedron(const triangle& _base, const vector& _apex)
+	 : base(_base)
+	 , apex(_apex)
+	{ }
+
+	const vector& a(void) const {return base.a;}
+	const vector& b(void) const {return base.b;}
+	const vector& c(void) const {return base.c;}
+	const vector& d(void) const {return apex;}
+
+	double volume(void) const
+	{
+		return fabs(((a()-d())*((b()-d())%(c()-d()))))/6.0;
+	}
+};
+
+
+/** The general implementation of the input user interface template.
+ *  Upon construction prints-out a banner and uses a factory
+ *  configured to use the same input user interface to construct
+ *  the Product.
+ */
+template <class Product>
+struct input_ui
+{
+	struct banner
+	{
+		template <class Context, class ConstrIndex, class ParamIndex>
+		banner(Context* pc, ConstrIndex ci, ParamIndex pi)
+		{
+			::std::cout << 
+				"Construct " << 
+				BOOST_MIRRORED_TYPE(Product)::full_name() << 
+				" " << 
+				boost::mirror::meta_constructors<
+					Context
+				>::base_param_name(ci, pi) <<
+				::std::endl;
+		}
+	} b;
+
+	typename ::boost::mirror::make_factory< input_ui, Product >::type f;
+
+	template <class Context, class ConstrIndex, class ParamIndex>
+	input_ui(int _x, Context* pc, ConstrIndex ci, ParamIndex pi)
+	 : b(pc, ci, pi)
+	 , f(_x)
+	{ }
+
+	inline Product operator()(void)
+	{
+		return f();
+	}
+};
+
+/** Specialization of the input interface, used to produce
+ *  doubles by prompting the user to enter a value on the 
+ *  console.
+ */
+template <> 
+struct input_ui<double>
+{
+	double x;
+
+	template <class Context, class ConstrIndex, class ParamIndex>
+	input_ui(int _x, Context* pc, ConstrIndex ci, ParamIndex pi)
+	{
+                ::std::cout <<
+                        "Enter " << 
+			BOOST_MIRRORED_TYPE(double)::full_name() << 
+			" " << 
+			boost::mirror::meta_constructors<
+				Context
+			>::base_param_name(ci, pi) <<
+			" = " <<
+                        ::std::flush;
+		::std::cin >> x;
+	}
+
+	inline double operator()(void)
+	{
+		return x;
+	}
+};
+
+/** A manager of this input user interface, which picks the 
+ *  constructor that will be used by the means of the result
+ *  of the index member function (i.e. the zero-th registered
+ *  constructor will be always used with this manager).
+ */
+template <>
+struct input_ui<void>
+{
+
+	input_ui(int _x, int factory_index)
+	{ }
+
+	input_ui(const char* names[], int factory_index)
+	{
+		::std::cout << "Create " << names[factory_index]  << ::std::endl;
+	}
+
+	inline int param(void) const 
+	{
+		// no params
+		return 0;
+	}
+
+	inline int index(void) 
+	{
+		return 0;
+	}
+};
+
+} // namespace test 
+
+
+namespace boost {
+namespace mirror {
+
+// register the ::test namespace
+BOOST_MIRROR_REG_NAMESPACE( (test) )
+
+// register the vector, triangle and tetrahedron classes
+BOOST_MIRROR_REG_TYPE( ::test, vector)
+BOOST_MIRROR_REG_TYPE( ::test, triangle)
+BOOST_MIRROR_REG_TYPE( ::test, tetrahedron)
+
+// register the constructors of ::test::vector
+BOOST_MIRROR_REG_CONSTRUCTORS_BEGIN( ::test::vector )
+	BOOST_MIRROR_REG_CONSTRUCTOR(0, 
+		((double)(x))((double)(y))((double)(z))
+	)
+	BOOST_MIRROR_REG_DEFAULT_CONSTRUCTOR(1)
+BOOST_MIRROR_REG_CONSTRUCTORS_END
+
+// register the constructor of ::test::triangle
+BOOST_MIRROR_REG_CONSTRUCTORS_BEGIN( ::test::triangle )
+	BOOST_MIRROR_REG_CONSTRUCTOR(0, 
+		((::test::vector)(a))((::test::vector)(b))((::test::vector)(c))
+	)
+BOOST_MIRROR_REG_CONSTRUCTORS_END
+
+// register the constructor of ::test::tetrahedron
+BOOST_MIRROR_REG_CONSTRUCTORS_BEGIN( ::test::tetrahedron )
+	BOOST_MIRROR_REG_CONSTRUCTOR(0, 
+		((::test::triangle)(base))((::test::vector)(apex))
+	)
+BOOST_MIRROR_REG_CONSTRUCTORS_END
+
+} // namespace mirror
+} // namespace boost
+
+
+int main(void)
+{
+	using namespace ::std;
+	using namespace ::boost;
+	using namespace ::boost::mirror;
+	//
+	// create a factory plugged with the input ui
+	const char* param_names[] = {"a tetrahedron"};
+	factory< ::test::input_ui, ::test::tetrahedron > f(param_names, 0);
+	// use the factory to construct a tetrahedron and calculate 
+	// it's volume and base area
+	::test::tetrahedron t(f());
+	// ... and print them out
+	cout << "the volume is " << t.volume() << endl;
+	cout << "the area of the base is " << t.base.area() << endl;
+	//
+	return 0;
+}
+