SAGA C++ API 1.6
task_get_result_impl.hpp
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines