poly_drag_and_drop_converter.hpp
Go to the documentation of this file.
00001 /* 00002 Copyright 2007 Adobe Systems Incorporated 00003 Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt 00004 or a copy at http://stlab.adobe.com/licenses.html) 00005 */ 00006 00007 /**************************************************************************************************/ 00008 00009 #ifndef ADOBE_POLY_DRAG_AND_DROP_CONVERTER_HPP 00010 #define ADOBE_POLY_DRAG_AND_DROP_CONVERTER_HPP 00011 00012 /**************************************************************************************************/ 00013 00014 #include <adobe/config.hpp> 00015 00016 #include <adobe/any_regular.hpp> 00017 #include <adobe/poly.hpp> 00018 #include <adobe/future/drag_and_drop_converter_concept.hpp> 00019 00020 #include <boost/bind.hpp> 00021 #include <boost/type_traits/function_traits.hpp> 00022 #include <boost/type_traits/remove_pointer.hpp> 00023 #include <boost/type_traits/remove_reference.hpp> 00024 #include <boost/type_traits/remove_const.hpp> 00025 00026 /**************************************************************************************************/ 00027 00028 namespace adobe { 00029 00030 /**************************************************************************************************/ 00031 00032 struct poly_drag_and_drop_converter_interface : poly_copyable_interface 00033 { 00034 virtual any_regular_t convert(const any_regular_t& new_value) const = 0; 00035 }; 00036 00037 /**************************************************************************************************/ 00038 00039 template <typename T> 00040 struct poly_drag_and_drop_converter_instance : optimized_storage_type<T, poly_drag_and_drop_converter_interface>::type 00041 { 00042 typedef typename optimized_storage_type<T, poly_drag_and_drop_converter_interface>::type base_t; 00043 00044 BOOST_CLASS_REQUIRE(T, adobe, DragAndDropConverterConcept); 00045 00046 poly_drag_and_drop_converter_instance(move_from<poly_drag_and_drop_converter_instance> x) : 00047 base_t(move_from<base_t>(x.source)) 00048 { } 00049 00050 poly_drag_and_drop_converter_instance(const T& x) : 00051 base_t(x) 00052 { } 00053 00054 any_regular_t convert(const any_regular_t& new_value) const 00055 { 00056 typedef typename DragAndDropConverterConcept<T>::source_type const_source_type; 00057 typedef typename boost::remove_const<const_source_type>::type source_type; 00058 typedef typename DragAndDropConverterConcept<T>::dest_type const_dest_type; 00059 typedef typename boost::remove_const<const_dest_type>::type dest_type; 00060 00061 return any_regular_t(DragAndDropConverterConcept<T>::convert(this->get(), 00062 new_value.cast<source_type>())); 00063 } 00064 }; 00065 00066 /**************************************************************************************************/ 00067 00068 struct drag_and_drop_converter : poly_base<poly_drag_and_drop_converter_interface, 00069 poly_drag_and_drop_converter_instance> 00070 { 00071 typedef poly_base<poly_drag_and_drop_converter_interface, 00072 poly_drag_and_drop_converter_instance> base_t; 00073 00074 template <typename T> 00075 explicit drag_and_drop_converter(const T& s) : 00076 base_t(s) 00077 { } 00078 00079 drag_and_drop_converter(move_from<drag_and_drop_converter> x) 00080 : base_t(move_from<base_t>(x.source)) {} 00081 00082 template <typename V> 00083 any_regular_t convert(const V& new_value) const 00084 { return interface_ref().convert(any_regular_t(new_value)); } 00085 }; 00086 00087 /**************************************************************************************************/ 00088 00089 typedef poly<drag_and_drop_converter> poly_drag_and_drop_converter_t; 00090 00091 /**************************************************************************************************/ 00092 00093 #if !defined(ADOBE_NO_DOCUMENTATION) 00094 00095 /**************************************************************************************************/ 00096 00097 namespace implementation { 00098 00099 /**************************************************************************************************/ 00100 00101 template <typename Function> 00102 struct function_as_drag_and_drop_converter 00103 { 00104 typedef typename boost::remove_pointer<Function>::type function_type; 00105 typedef typename boost::function_traits<function_type>::result_type result_type; 00106 typedef typename boost::function_traits<function_type>::arg1_type arg_type; 00107 typedef result_type dest_type; 00108 typedef typename boost::remove_reference<arg_type>::type source_type; 00109 00110 // MM: To do: write Callable1Concept 00111 // BOOST_CLASS_REQUIRE2(Function, const source_type&, adobe, Callable1Concept) 00112 00113 explicit function_as_drag_and_drop_converter(const Function& f) : f_m(f) { } 00114 00115 inline dest_type convert(const source_type& x) const { return f_m(x); } 00116 00117 // MM: hack so as to work with non-regular F's 00118 friend inline bool operator==(const function_as_drag_and_drop_converter&, 00119 const function_as_drag_and_drop_converter&) 00120 { return true; } 00121 00122 Function f_m; 00123 }; 00124 00125 /**************************************************************************************************/ 00126 00127 } //namespace implementation 00128 00129 /**************************************************************************************************/ 00130 00131 #endif 00132 00133 /**************************************************************************************************/ 00137 template <typename Function> 00138 inline poly_drag_and_drop_converter_t make_function_as_poly_drag_and_drop_converter(const Function& f) 00139 { 00140 return poly_drag_and_drop_converter_t( 00141 implementation::function_as_drag_and_drop_converter<Function>(f)); 00142 } 00143 00144 /**************************************************************************************************/ 00145 00146 } // namespace adobe 00147 00148 /**************************************************************************************************/ 00149 00150 // ADOBE_POLY_DRAG_AND_DROP_CONVERTER_HPP 00151 #endif 00152 00153 /**************************************************************************************************/ |