Boost logo

Boost-Commit :

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;
+}
+


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