Mirror reflection library 0.5.13
|
This example shows how to extend the script factory generator plugin to support simple expressions like random() and the use of a factory generated by this plugin
Copyright 2006-2011 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 <mirror/factory.hpp> #include <mirror/meta_type.hpp> #include <mirror/utils/script_factory.hpp> #include <iostream> #include <cstdlib> #include "./tetrahedron.hpp" MIRROR_NAMESPACE_BEGIN template <typename Iterator> class my_custom_matcher : public aux::script_fact_ext_matcher<Iterator> { protected: // match one of the know expressions returning a double template <class Matcher> static double match_expr( Matcher& matcher, Iterator& i, Iterator e, Iterator& expr_begin, Iterator& expr_end, int& expr_id, double* ) { expr_begin = i; // here we support only yhe random() expression // returning a random number if(matcher.match(i, e, "random()")) { expr_end = i; expr_id = 0; return 1.0; } expr_id = -1; return 0.0; } public: // get a value tied to the expression matched in match_expr static double get(Iterator begin, Iterator end, int expr_id, double*) { // if we matched something it must have been random(): id = 0 assert(expr_id == 0); // return a random double in the range (0.0-48.0) return std::rand() % 48; } }; MIRROR_NAMESPACE_END int main(void) { using namespace mirror; using namespace test; MIRROR_USING_NAMESPACE(test); // // make the input object for the factory typedef script_fact_custom_traits< const char*, my_custom_matcher > my_custom_traits; script_fact_data<my_custom_traits> in; // create a factory plugged with the script parser factory_maker< script_fact_manuf, script_fact_suppl, script_fact_enum, my_custom_traits >::factory<tetrahedron>::type f = in.data(); // const char input[] = { "tetrahedron( \ triangle( \ vector(random(), 0, 0), \ vector(0, 1, 0), \ vector() \ ), \ vector(0, 0, random()) \ )" }; in.set(input, input + sizeof(input)); for(int i=0;i!=10;++i) { // use the factory to construct a tetrahedron and calculate // its volume and base area tetrahedron t(f()); // ... and print them out std::cout << "the volume is " << t.volume() << " " << std::flush; std::cout << "the area of the base is " << t.base.area() << std::endl; } // return 0; } /* Example of output: the volume is 25.6667 the area of the base is 11 the volume is 28.5 the area of the base is 9.5 the volume is 87.8333 the area of the base is 15.5 the volume is 20 the area of the base is 6 the volume is 19.5 the area of the base is 6.5 the volume is 186.333 the area of the base is 21.5 the volume is 14.3333 the area of the base is 21.5 the volume is 128.333 the area of the base is 11 the volume is 36 the area of the base is 9 the volume is 26.6667 the area of the base is 20 */