TuttleOFX
1
|
00001 #ifndef _TUTTLE_HOST_ATTRIBUTE_EXPRESSION_HPP_ 00002 #define _TUTTLE_HOST_ATTRIBUTE_EXPRESSION_HPP_ 00003 00004 #include <tuttle/host/exceptions.hpp> 00005 00006 #ifdef TUTTLE_HOST_WITH_PYTHON_EXPRESSION 00007 #include <boost/python.hpp> 00008 #else 00009 #include <boost/lexical_cast.hpp> 00010 #endif 00011 00012 namespace tuttle { 00013 namespace host { 00014 namespace attribute { 00015 00016 #ifdef TUTTLE_HOST_WITH_PYTHON_EXPRESSION 00017 namespace expression_details { 00018 00019 inline boost::python::object pythonObjectFromExpression( const std::string& expression ) 00020 { 00021 using namespace boost; 00022 std::string fullExp( 00023 "from math import *\n" 00024 "import os\n" 00025 "import sys\n" 00026 ); 00027 00028 python::object main = python::import( "__main__" ); 00029 python::object global( main.attr( "__dict__" ) ); 00030 python::exec( fullExp.c_str( ), global ); 00031 return python::eval( expression.c_str( ), global, global ); 00032 } 00033 00034 template< typename Type > 00035 inline Type extractValueFromPythonObject( const boost::python::object& result ) 00036 { 00037 using namespace boost; 00038 try 00039 { 00040 Type res = python::extract<Type>(result) BOOST_EXTRACT_WORKAROUND; 00041 return res; 00042 } 00043 catch( ... ) 00044 { 00045 BOOST_THROW_EXCEPTION( exception::Value() 00046 << exception::user() + "Can't extract value from expression." 00047 << exception::dev() + boost::current_exception_diagnostic_information() 00048 ); 00049 } 00050 } 00051 00052 } // end namespace 00053 00054 template< typename Type > 00055 inline Type extractValueFromExpression( const std::string& expression ) 00056 { 00057 using namespace boost; 00058 try 00059 { 00060 python::object result = expression_details::pythonObjectFromExpression( expression ); 00061 return expression_details::extractValueFromPythonObject<Type>( result ); 00062 } 00063 catch( ... ) 00064 { 00065 BOOST_THROW_EXCEPTION( exception::Value() 00066 << exception::user() + "Syntaxe error for expression: \"" + expression + "\"" 00067 << exception::dev() + boost::current_exception_diagnostic_information() 00068 ); 00069 } 00070 } 00071 00072 template<> 00073 inline std::string extractValueFromExpression<std::string>( const std::string& expression ) 00074 { 00075 using namespace boost; 00076 typedef std::string Type; 00077 try 00078 { 00079 python::object result = expression_details::pythonObjectFromExpression( expression ); 00080 return expression_details::extractValueFromPythonObject<Type>( result ); 00081 } 00082 catch( ... ) 00083 { 00084 return expression; 00085 } 00086 } 00087 00088 #else 00089 00090 template< typename Type > 00091 inline Type extractValueFromExpression( const std::string& expression ) 00092 { 00093 try 00094 { 00095 return boost::lexical_cast<Type>( expression ); 00096 } 00097 catch( ... ) 00098 { 00099 BOOST_THROW_EXCEPTION( exception::Value() 00100 << exception::user() + "Syntaxe error for expression: \"" + expression + "\"" 00101 << exception::dev() + boost::current_exception_diagnostic_information() 00102 ); 00103 } 00104 } 00105 00106 #endif 00107 00108 } 00109 } 00110 } 00111 00112 00113 #endif 00114