SAGA Adaptor CPI v.1.0
|
00001 // Copyright (c) 2005-2009 Hartmut Kaiser 00002 // 00003 // Distributed under the Boost Software License, Version 1.0. (See accompanying 00004 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 00005 00006 #include <utility> 00007 #include <vector> 00008 #include <string> 00009 00010 #include <boost/assert.hpp> 00011 #include <boost/lexical_cast.hpp> 00012 00013 #include <saga/saga/task.hpp> 00014 #include <saga/saga/url.hpp> 00015 #include <saga/saga/util.hpp> 00016 00017 #include <saga/impl/task.hpp> // include the task implementation we want to use 00018 00019 namespace saga 00020 { 00022 namespace detail 00023 { 00024 template <typename T> 00025 struct disable_reconvert : is_saga_object<T> {}; 00026 00027 template <typename T> 00028 struct disable_reconvert<std::vector<T> > : boost::mpl::true_ {}; 00029 00030 template <typename Retval> 00031 struct reconvert_result 00032 { 00033 template <typename Task> 00034 static Retval& call(Task& t, boost::mpl::false_) 00035 { 00036 // if the type we're interested in isn't directly supported, try to 00037 // get a std::string assuming it can be converted explicitly 00038 std::string* str_retval = saga::detail::any_cast<std::string>( 00039 &get_task_result(t)); 00040 00041 if (0 != str_retval) 00042 { 00043 // now try to convert 00044 try { 00045 // re-assign stored value 00046 get_task_result(t).assign( 00047 boost::lexical_cast<Retval>(*str_retval)); 00048 00049 // re-fetch the sored value 00050 Retval* retval = saga::detail::any_cast<Retval>( 00051 &get_task_result(t)); 00052 if (0 != retval) 00053 return *retval; 00054 } 00055 catch (boost::bad_lexical_cast const&) { 00056 ; // just fall through 00057 } 00058 } 00059 00060 // give up 00061 SAGA_THROW_VERBATIM(t, 00062 "Wrong data type requested while calling get_result", 00063 saga::NoSuccess); 00064 00065 static Retval static_retval; 00066 return static_retval; 00067 } 00068 00069 template <typename Task> 00070 static Retval& call(Task& t, boost::mpl::true_) 00071 { 00072 // just give up 00073 SAGA_THROW_VERBATIM(t, 00074 "Wrong data type requested while calling get_result", 00075 saga::NoSuccess); 00076 00077 static Retval static_retval; 00078 return static_retval; 00079 } 00080 00081 template <typename Task> 00082 static Retval& call(Task& t) 00083 { 00084 typedef boost::mpl::bool_<disable_reconvert<Retval>::value> 00085 predicate; 00086 return call(t, predicate()); 00087 } 00088 }; 00089 } 00090 00091 // implement the get_result functions for the saga::task object 00092 template <typename Retval> 00093 Retval& task::get_result() 00094 { 00095 if (saga::task_base::Failed == get_task_if()->get_state()) 00096 { 00097 get_task_if()->rethrow(); // must throw 00098 } 00099 00100 Retval* retval = saga::detail::any_cast<Retval>( 00101 &get_task_result(*this)); 00102 if (0 == retval) 00103 return detail::reconvert_result<Retval>::call(*this); 00104 00105 return *retval; 00106 } 00107 00108 template <typename Retval> 00109 Retval const& task::get_result() const 00110 { 00111 if (saga::task_base::Failed == get_task_if()->get_state()) 00112 { 00113 get_task_if()->rethrow(); // must throw 00114 } 00115 00116 Retval const* retval = saga::detail::any_cast<Retval const>( 00117 &get_task_result(*this)); 00118 if (0 == retval) 00119 return detail::reconvert_result<Retval>::call(*this); 00120 00121 return *retval; 00122 } 00124 } 00125